Git Product home page Git Product logo

asyncplusplus's Introduction

Async++

Async++ is a lightweight concurrency framework for C++11. The concept was inspired by the Microsoft PPL library and the N3428 C++ standard proposal.

Example

Here is a short example which shows some features of Async++:

#include <iostream>
#include <async++.h>

int main()
{
    auto task1 = async::spawn([] {
        std::cout << "Task 1 executes asynchronously" << std::endl;
    });
    auto task2 = async::spawn([]() -> int {
        std::cout << "Task 2 executes in parallel with task 1" << std::endl;
        return 42;
    });
    auto task3 = task2.then([](int value) -> int {
        std::cout << "Task 3 executes after task 2, which returned "
                  << value << std::endl;
        return value * 3;
    });
    auto task4 = async::when_all(task1, task3);
    auto task5 = task4.then([](std::tuple<async::task<void>,
                                          async::task<int>> results) {
        std::cout << "Task 5 executes after tasks 1 and 3. Task 3 returned "
                  << std::get<1>(results).get() << std::endl;
    });

    task5.get();
    std::cout << "Task 5 has completed" << std::endl;

    async::parallel_invoke([] {
        std::cout << "This is executed in parallel..." << std::endl;
    }, [] {
        std::cout << "with this" << std::endl;
    });

    async::parallel_for(async::irange(0, 5), [](int x) {
        std::cout << x;
    });
    std::cout << std::endl;

    int r = async::parallel_reduce({1, 2, 3, 4}, 0, [](int x, int y) {
        return x + y;
    });
    std::cout << "The sum of {1, 2, 3, 4} is " << r << std::endl;
}

// Output (order may vary in some places):
// Task 1 executes asynchronously
// Task 2 executes in parallel with task 1
// Task 3 executes after task 2, which returned 42
// Task 5 executes after tasks 1 and 3. Task 3 returned 126
// Task 5 has completed
// This is executed in parallel...
// with this
// 01234
// The sum of {1, 2, 3, 4} is 10

Supported Platforms

The only requirement to use Async++ is a C++11 compiler and standard library. Unfortunately C++11 is not yet fully implemented on most platforms. Here is the list of OS and compiler combinations which are known to work.

  • Linux: Works with GCC 4.7+, Clang 3.2+ and Intel compiler 15+.
  • Mac: Works with Apple Clang (using libc++). GCC also works but you must get a recent version (4.7+).
  • iOS: Works with Apple Clang (using libc++). Note: because iOS has no thread local support, the library uses a workaround based on pthreads.
  • Windows: Works with GCC 4.8+ (with pthread-win32) and Visual Studio 2013+.

Building and Installing

Instructions for compiling Async++ and using it in your code are available on the Building and Installing page.

Documentation

The Async++ documentation is split into four parts:

  • Tasks: This describes task objects which are the core Async++. Reading this first is strongly recommended.
  • Parallel algorithms: This describes functions to run work on ranges in parallel.
  • Schedulers: This describes the low-level details of Async++ and how to customize it.
  • API Reference: This gives detailed descriptions of all the classes and functions available in Async++.

Contact

You can contact me by email at [email protected].

asyncplusplus's People

Contributors

amanieu avatar amosbird avatar botellaa avatar burning-daylight avatar fpelliccioni avatar ianlilleyt avatar lucidsigma avatar museghost avatar rogiel avatar tribal-tec avatar zerodefect avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asyncplusplus's Issues

Custom scheduler for Android and iOS

Been trying to use asyncplusplus on iOS and Android.
Works well so far when used only on the C++ side. But once one starts doing complex things (UI scheduling typically, completely different on iOS and Android), things get complicated.
I have seen the gtk_scheduler example. I was wondering how one could write a custom scheduler using libdispatch for iOS and ALooper for Android.
Any hint/help would be much appreciated.

Null Pointer Access

Accessing the smart pointer after it is moved does not make sense. This way if an exception is thrown in the try block the code will always fail.

// Run a single continuation
template<typename Sched>
void run_continuation(Sched& sched, task_ptr&& cont)
{
LIBASYNC_TRY {
detail::schedule_task(sched, std::move(cont));
} LIBASYNC_CATCH(...) {
// This is suboptimal, but better than letting the exception leak
cont->vtable->cancel(cont.get(), std::current_exception());
}
}

[question] Build both static and dynamic versions of the library

According to the wiki, build option BUILD_SHARED_LIBS permits to select between static and dynamic versions of the library to build.
Is there any way to build at the same time (without re-configuring the build) the both versions?
I want to create a FreeBSD port of the library (it works correctly under FreeBSD), and I would like to install both versions by default.

async::when_any crashes

The following code crashes often with Clang 8.0 on MacOSX , what am I doing wrong ?

#include <iostream>
#include <array>
#include <async++.h>

int main ()
{
  std::array<async::task<char>,3> tasks {
    async::spawn([] {return 'A';}),
    async::spawn([] {return 'B';}),
    async::spawn([] {return 'C';}),
  };

  async::when_any(tasks.begin(),tasks.end()).then(
  [](async::when_any_result<std::vector<async::task<char>>> result) {
    std::cout << "Task " << result.index << " finished with value "
              << result.tasks[result.index].get() << std::endl;
  });
  return 0;
}

arm gcc 4.8 error

/opt/arm-2014/arm-2014.05//bin/arm-none-linux-gnueabi-g++ -DLIBASYNC_STATIC -isystem /home/cyc/oscmake/3rdparty/asyncplusplus/include -g -std=gnu++11 -o CMakeFiles/asyncplusplus.out.dir/src/asyncplusplus.cpp.o -c /home/cyc/oscmake/src/asyncplusplus.cpp
[build] /usr/bin/make -f CMakeFiles/serial.out.dir/build.make CMakeFiles/serial.out.dir/depend
[build] make[2]: Entering directory '/home/cyc/oscmake/build'
[build] cd /home/cyc/oscmake/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/cyc/oscmake /home/cyc/oscmake /home/cyc/oscmake/build /home/cyc/oscmake/build /home/cyc/oscmake/build/CMakeFiles/serial.out.dir/DependInfo.cmake --color=
[build] make[2]: Leaving directory '/home/cyc/oscmake/build'
[build] /usr/bin/make -f CMakeFiles/serial.out.dir/build.make CMakeFiles/serial.out.dir/build
[build] make[2]: Entering directory '/home/cyc/oscmake/build'
[build] make[2]: Nothing to be done for 'CMakeFiles/serial.out.dir/build'.
[build] make[2]: Leaving directory '/home/cyc/oscmake/build'
[build] [ 90%] Built target serial.out
[build] In file included from /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++.h:141:0,
[build] from /home/cyc/oscmake/src/asyncplusplus.cpp:2:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:55:34: error: 'std::exception_ptr' has not been declared
[build] void (cancel)(task_base, std::exception_ptr&&) LIBASYNC_NOEXCEPT;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::task_base::run_continuation(Sched&, async::detail::task_ptr&&)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:104:37: error: 'current_exception' is not a member of 'std'
[build] cont->vtable->cancel(cont.get(), std::current_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: At global scope:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:31: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:70: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:70: error: 'exception_ptr' is not a member of 'std'
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:88: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:96: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:96: error: template argument 2 is invalid
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:99: error: expected ';' at end of member declaration
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:170:104: error: 'except' does not name a type
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:31: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:70: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:70: error: 'exception_ptr' is not a member of 'std'
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:88: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:96: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:96: error: template argument 2 is invalid
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:99: error: expected ';' at end of member declaration
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:211:104: error: 'except' does not name a type
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:31: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:70: error: 'exception_ptr' is not a member of 'std'
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:70: error: 'exception_ptr' is not a member of 'std'
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:88: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:96: error: template argument 1 is invalid
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:96: error: template argument 2 is invalid
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:99: error: expected ';' at end of member declaration
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:236:104: error: 'except' does not name a type
[build] std::aligned_storage<sizeof(std::exception_ptr), std::alignment_ofstd::exception_ptr::value>::type except;
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:274:24: error: 'std::exception_ptr' has not been declared
[build] void cancel_base(std::exception_ptr&& except_)
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:282:26: error: 'std::exception_ptr' has not been declared
[build] void set_exception(std::exception_ptr&& except_)
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:288:2: error: 'exception_ptr' in namespace 'std' does not name a type
[build] std::exception_ptr& get_exception()
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In destructor 'async::detail::task_result::~task_result()':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:21: error: expected type-specifier
[build] reinterpret_caststd::exception_ptr*(&this->except)->~exception_ptr();
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:21: error: expected '>'
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:21: error: expected '('
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:21: error: 'exception_ptr' is not a member of 'std'
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:40: error: expected primary-expression before '>' token
[build] reinterpret_caststd::exception_ptr*(&this->except)->~exception_ptr();
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:270:74: error: expected ')' before ';' token
[build] reinterpret_caststd::exception_ptr*(&this->except)->~exception_ptr();
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::task_result::set_exception(int&&)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:284:22: error: expected type-specifier
[build] new(&this->except) std::exception_ptr(std::move(except_));
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:284:22: error: expected ';'
[build] In file included from /home/cyc/oscmake/src/asyncplusplus.cpp:2:0:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::task_result::wait_and_throw()':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:297:4: error: 'rethrow_exception' is not a member of 'std'
[build] LIBASYNC_RETHROW_EXCEPTION(get_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:297:4: error: there are no arguments to 'get_exception' that depend on a template parameter, so a declaration of 'get_exception' must be available [-fpermissive]
[build] LIBASYNC_RETHROW_EXCEPTION(get_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:297:4: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
[build] In file included from /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++.h:141:0,
[build] from /home/cyc/oscmake/src/asyncplusplus.cpp:2:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: At global scope:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:405:40: error: 'std::exception_ptr' has not been declared
[build] static void cancel(task_base* t, std::exception_ptr&& except) LIBASYNC_NOEXCEPT
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In static member function 'static void async::detail::task_func<Sched, Func, Result>::run(async::detail::task_base*)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:400:14: error: 'current_exception' is not a member of 'std'
[build] cancel(t, std::current_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::unwrapped_func<Result, Child>::operator()(Child) const':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:473:25: error: 'exception_ptr' is not a member of 'std'
[build] parent->cancel_base(std::exception_ptr(get_internal_task(child_task)->get_exception()));
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:477:24: error: 'current_exception' is not a member of 'std'
[build] parent->cancel_base(std::current_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In function 'void async::detail::unwrapped_finish(async::detail::task_base*, Child)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:495:63: error: 'current_exception' is not a member of 'std'
[build] static_cast<task_result>(parent_base)->cancel_base(std::current_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::continuation_exec_func<Sched, Parent, Result, Func, std::integral_constant<bool, true>, false>::operator()(async::detail::task_base
)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:548:64: error: 'exception_ptr' is not a member of 'std'
[build] task_func<Sched, continuation_exec_func, Result>::cancel(t, std::exception_ptr(get_internal_task(parent)->get_exception()));
[build] ^
[build] In file included from /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++.h:141:0,
[build] from /home/cyc/oscmake/src/asyncplusplus.cpp:2:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::continuation_exec_func<Sched, Parent, Result, Func, async::detail::fake_void, false>::operator()(async::detail::task_base*)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:565:64: error: 'exception_ptr' is not a member of 'std'
[build] task_func<Sched, continuation_exec_func, Result>::cancel(t, std::exception_ptr(get_internal_task(parent)->get_exception()));
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::continuation_exec_func<Sched, Parent, Result, Func, std::integral_constant<bool, true>, true>::operator()(async::detail::task_base*)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:593:64: error: 'exception_ptr' is not a member of 'std'
[build] task_func<Sched, continuation_exec_func, Result>::cancel(t, std::exception_ptr(get_internal_task(parent)->get_exception()));
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h: In member function 'void async::detail::continuation_exec_func<Sched, Parent, Result, Func, async::detail::fake_void, true>::operator()(async::detail::task_base*)':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task_base.h:607:64: error: 'exception_ptr' is not a member of 'std'
[build] task_func<Sched, continuation_exec_func, Result>::cancel(t, std::exception_ptr(get_internal_task(parent)->get_exception()));
[build] ^
[build] In file included from /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++.h:142:0,
[build] from /home/cyc/oscmake/src/asyncplusplus.cpp:2:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/scheduler.h: In destructor 'async::task_run_handle::~task_run_handle()':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/scheduler.h:121:41: error: 'make_exception_ptr' is not a member of 'std'
[build] handle->vtable->cancel(handle.get(), std::make_exception_ptr(task_not_executed()));
[build] ^
[build] In file included from /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++.h:143:0,
[build] from /home/cyc/oscmake/src/asyncplusplus.cpp:2:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h: At global scope:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:118:2: error: 'exception_ptr' in namespace 'std' does not name a type
[build] std::exception_ptr get_exception() const
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:218:26: error: 'std::exception_ptr' has not been declared
[build] bool set_exception(std::exception_ptr except) const
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h: In member function 'bool async::detail::basic_event::set_internal(T&&) const':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:166:42: error: 'current_exception' is not a member of 'std'
[build] get_internal_task(*this)->cancel_base(std::current_exception());
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h: In destructor 'async::detail::basic_event::~basic_event()':
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:197:18: error: 'make_exception_ptr' is not a member of 'std'
[build] set_exception(std::make_exception_ptr(abandoned_event_task()));
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h: At global scope:
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:466:2: error: 'exception_ptr' in namespace 'std' does not name a type
[build] std::exception_ptr get_exception() const
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:545:34: error: template declaration of 'async::task async::make_exception_task'
[build] task make_exception_task(std::exception_ptr except)
[build] ^
[build] /home/cyc/oscmake/3rdparty/asyncplusplus/include/async++/task.h:545:29: error: 'exception_ptr' is not a member of 'std'
[build] task make_exception_task(std::exception_ptr except)
[build] ^
[build] make[2]: *** [CMakeFiles/asyncplusplus.out.dir/build.make:66: CMakeFiles/asyncplusplus.out.dir/src/asyncplusplus.cpp.o] Error 1
[build] make[2]: Leaving directory '/home/cyc/oscmake/build'
[build] make[1]: Leaving directory '/home/cyc/oscmake/build'
[build] make[1]: *** [CMakeFiles/Makefile2:679: CMakeFiles/asyncplusplus.out.dir/all] Error 2
[build] make: *** [Makefile:120: all] Error 2
[build] Build finished with exit code 2

$ /opt/arm-2014/arm-2014.05//bin/arm-none-linux-gnueabi-g++ -vUsing built-in specs.
COLLECT_GCC=/opt/arm-2014/arm-2014.05//bin/arm-none-linux-gnueabi-g++
COLLECT_LTO_WRAPPER=/opt/arm-2014/arm-2014.05/bin/../libexec/gcc/arm-none-linux-gnueabi/4.8.3/lto-wrapper
Target: arm-none-linux-gnueabi
Configured with: /scratch/maciej/arm-linux-2014.05-rel/src/gcc-4.8-2014.05/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --enable-extra-sgxxlite-multilibs --with-arch=armv5te --with-gnu-as --with-gnu-ld --with-specs='%{save-temps: -fverbose-asm} %{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables} -D__CS_SOURCERYGXX_MAJ__=2014 -D__CS_SOURCERYGXX_MIN__=5 -D__CS_SOURCERYGXX_REV__=29' --enable-languages=c,c++ --enable-shared --enable-lto --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery CodeBench Lite 2014.05-29' --with-bugurl=https://sourcery.mentor.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc --with-build-sysroot=/scratch/maciej/arm-linux-2014.05-rel/install/opt/codesourcery/arm-none-linux-gnueabi/libc --with-gmp=/scratch/maciej/arm-linux-2014.05-rel/obj/pkg-2014.05-29-arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpfr=/scratch/maciej/arm-linux-2014.05-rel/obj/pkg-2014.05-29-arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-mpc=/scratch/maciej/arm-linux-2014.05-rel/obj/pkg-2014.05-29-arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-isl=/scratch/maciej/arm-linux-2014.05-rel/obj/pkg-2014.05-29-arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --with-cloog=/scratch/maciej/arm-linux-2014.05-rel/obj/pkg-2014.05-29-arm-none-linux-gnueabi/arm-2014.05-29-arm-none-linux-gnueabi.extras/host-libs-i686-pc-linux-gnu/usr --disable-libgomp --disable-libitm --enable-libatomic --disable-libssp --enable-poison-system-directories --with-build-time-tools=/scratch/maciej/arm-linux-2014.05-rel/install/opt/codesourcery/arm-none-linux-gnueabi/bin --with-build-time-tools=/scratch/maciej/arm-linux-2014.05-rel/install/opt/codesourcery/arm-none-linux-gnueabi/bin SED=sed
Thread model: posix
gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29)

cyc@cqset ~/oscmake master
$

error on centos 7

I tried to compile my project using async++ for the first time on Centos7 using gcc 4.8.2 and I got this error:

undefined reference to `void std::atomic_init<async::detail::compressed_ptr<3ul, true> >(std::atomic<async::detail::compressed_ptr<3ul, true> >*, async::detail::compressed_ptr<3ul, true>)'

Does it mean something to you? Thanks for your help

MacOS: missing Obj-C autorelease pool handling

Most functions end up using native apis which create autorelease objects.
These objects would be effectively "leaked" if run through async++.

The thread pool/loop needs local per-iteration pool to match user expectations(or lack of).

sample Qt pool handling:

#ifdef __APPLE__
// Use the direct runtime interface to manage autorelease pools, as it
// has less overhead then allocating NSAutoreleasePools, and allows for
// a future where we use ARC (where NSAutoreleasePool is not allowed).
// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support
extern "C" {
    void *objc_autoreleasePoolPush(void);
    void objc_autoreleasePoolPop(void *pool);
}
    #define AUTORELEASE_THREAD_GUARD() auto poolDone = ScopedDefer([pool = objc_autoreleasePoolPush()](){ objc_autoreleasePoolPop(pool); });
#else
    #define AUTORELEASE_THREAD_GUARD()
#endif

Conan package

Related to #39.
It would be great to see this library in some conan repo for easier integration into own projects.

event_task and continuation

Hi, and thank you for this great project!

The output of the sample program below:

int main()
{
    std::cout << "main thread:" << std::this_thread::get_id() << std::endl;

    async::event_task<int> event;

    async::spawn(async::inline_scheduler(),[&event]() {
        std::cout << "event_task: " << std::this_thread::get_id() << std::endl;
        return event.get_task();
    }).then(async::inline_scheduler(),[](int) {
        std::cout << "continuation: " << std::this_thread::get_id() << std::endl;
    });
    event.set(5);
    return 0;
}

is something like:
main thread:139639703947136
event_task: 139639703947136
continuation: 139639666984704

Shouldn't everything run on the same thread?

ERROR: terminate called without an active exception on QT application

main.cpp

#include "mainwindow.h"
#include <iostream>
#include <QApplication>
#include "async++.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    auto task1 = async::spawn([] {
        std::cout << "Task 1 executes asynchronously" << std::endl;
    });



    auto task2 = async::spawn([]() -> int {
        std::cout << "Task 2 executes in parallel with task 1" << std::endl;
        return 42;
    });
    auto task3 = task2.then([](int value) -> int {
        std::cout << "Task 3 executes after task 2, which returned "
                  << value << std::endl;
        return value * 3;
    });
    auto task4 = async::when_all(task1, task3);
    auto task5 = task4.then([](std::tuple<async::task<void>,
                                          async::task<int>> results) {
        std::cout << "Task 5 executes after tasks 1 and 3. Task 3 returned "
                  << std::get<1>(results).get() << std::endl;
    });

    task5.get();
    std::cout << "Task 5 has completed" << std::endl;


    async::parallel_invoke([] {
        std::cout << "This is executed in parallel..." << std::endl;
    }, [] {
        std::cout << "with this" << std::endl;
    });

    async::parallel_for(async::irange(0, 5), [](int x) {
        std::cout << x;
    });
    std::cout << std::endl;

    int r = async::parallel_reduce({1, 2, 3, 4}, 0, [](int x, int y) {
        return x + y;
    });
    std::cout << "The sum of {1, 2, 3, 4} is " << r << std::endl;

    MainWindow w;
    w.show();

    return a.exec();
}

the window wouldn't show, and error message are:

terminate called without an active exception
terminate called recursively
terminate called recursively

how to run some tasks behind Window UI?

gcc 4.7 compatibility

The library does not compile with gcc-4.7.0 due to a "std::this_thread::yield()" problem which is known for the 4.7 version.
The error is:

asyncplusplus/include/async++/task.h: In destructor ‘async::local_task<Sched, Func>::~local_task()’:
asyncplusplus/include/async++/task.h:429:4: error: ‘yield’ is not a member of ‘std::this_thread’

Question about the Chase-Lev work stealing deque implementation

Excuse me if this is incorrect, but I thought that in the implementation of a Chase-Lev work stealing deque you do not need the elements of the circular array to be atomic; only the pointer to the circular array needs to be stored as atomic. What is the reason behind choosing to make all of the elements in the circular array atomic?

async block never invoked

I have some async block like

        async::spawn([this, &resource](){
            ... // resource loading here
        });

I call method that loads resources then it finishes its job. I call it one more time and all async blocks is never invoked anymore...

Proper way to add pre-execute and post-execute code to worker threads

Hello, how can I inject this code into async spawned thread's creation and destruction?

#include <cds/gc/hp.h>
int myThreadEntryPoint(void *)
{
    // Attach the thread to libcds infrastructure
    cds::threading::Manager::attachThread();
    // Now you can use HP-based containers in the thread
    //...
    // Detach thread when terminating
    cds::threading::Manager::detachThread();
}

task unwrapping usage

Not sure if I am missing something but the following code works

    // Create an event
     async::event_task<int> e;

    // Get a task associated with the event
    auto t = e.get_task();
    t
    .then([](int res)
    {
        printf("first");
        return async::spawn([] {
            return 42;
        });
    })
    .then([](int next)
    {
        printf("second");
    });

and transforming the first event_task from to gives a compilation error

    // Create an event
     async::event_task<void> e;

    // Get a task associated with the event
    auto t = e.get_task();
    t
    .then([]()
    {
        printf("first");
        return async::spawn([] {
            return 42;
        });
    })
    .then([](int next)
    {
        printf("second");
    });

Under Clang (Xcode 5.1)

task_base.h:556:70: No viable conversion from 'int' to 'async::detail::fake_void'

How to catch an exception with when_all()?

I do not understand how to handle exceptions in the case of a when_all().
Here is my simple example.

        std::vector< async::task< void > > tasks;
        for( int t = 0; t < 10; t++ )
        {
            tasks.emplace_back( async::spawn( [] {
                throw std::runtime_error( "Some list error" );
            } ) );
        }
        async::when_all( tasks.begin(), tasks.end() ).get();

I understood that get() (instead of wait()) would return the exception but nothing happened.

Thanks for your help!

task using unique_ptr

I have an issue with an example using unique_ptr.

auto value = std::make_unique< int >( 12 );
auto t1 = async::spawn( [&value] { std::cout << *value << std::endl; } );
async::when_all( t1 );

This code prints a random number instead of 12.
If I use t1.wait() instead of when_all, it works.

thread wainting for task to end should not run another task

Hello, thank you for the nice lib.

I will try to describe my problem.
The default scheduler runs several tasks, says A and B
Task A creates a temporary scheduler and wait on it's internal tasks with when_all(A_tasks).wait()
The waiting thread runs task B and this leads to a mess as B cannot be called from A.
A thread waiting for a task to end should not run another task.

need more examples of Composition

Wiki mentioned basic examples of each feature with static array of task.
Can we get more examples such as how to create dynamic list of tasks and use when_all().

Nested task spawning broken

When I use nested tasks with async::spawn() and async::get(), the synchronization doesn't work properly. This happens pretty consistently, and I am forced to never spawn tasks from tasks, which can be very limiting.

In the example below, some of the get()s will return before the work has completed, causing bugs.

Aside from this, the library is very convenient and works well.

Thanks!
Rob

void Function1()
{
	async::task<void> tasks[100];
	for (int t=0; t<100; t++)
	{
		tasks[t] = async::spawn([=]
		{
			Function2();
		});
	}

	for (int t=0; t<100; t++)
		tasks[t].get();
}

void Function2()
{
	async::task<void> tasks[100];
	for (int t=0; t<100; t++)
	{
		tasks[t] = async::spawn([=]
		{
			DoWork();
		});
	}

	for (int t=0; t<100; t++)
		tasks[t].get();
}

wait on parallel_for results

Is it possible to wait on parallel_for results to then synchronously use all the results together?
Or how is this issue solvable with your API? I was hoping parallel_for would return tasks that I could .when_all() on, but it's void.

Chain a subset of tasks

I have a container of N Tasks and I would like to add a continuation of n of these N tasks. The problem is that both n and N are only known at runtime. My best idea was to create a vector of reference_wrapper of the n tasks but it does not work.

I understand you do not develop this library anymore but do you have an idea of how to manage this? Or how to modify Async++ to add this feature?
Or do you know other libraries that could do it?

Thanks a lot for your help

OS X compiling with LLVM 3.5.1

Not an issue

This is not really an issue, just a few friendly hints to get asyncplusplus to compile on OS X.

Problem

Apple's version of clang, at least with the most recent Xcode, seems to be based on LLVM 3.5.0

You'll get a compile error wth the latest code on master:

In file included from /Users/laurens/Development/cpp/asyncplusplus/src/scheduler.cpp:21:
In file included from /Users/laurens/Development/cpp/asyncplusplus/src/internal.h:21:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:627:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:610:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/atomic:632:58: error: no viable conversion from 'async::detail::compressed_ptr<3, true>' to '_Atomic(async::detail::compressed_ptr<3, true>)'
    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
                                                         ^    ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/atomic:736:51: note: in instantiation of member function 'std::__1::__atomic_base<async::detail::compressed_ptr<3, true>, false>::__atomic_base' requested here
    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
                                                  ^
/Users/laurens/Development/cpp/asyncplusplus/include/async++/continuation_vector.h:120:5: note: in instantiation of member function 'std::__1::atomic<async::detail::compressed_ptr<3, true> >::atomic' requested here
                : atomic_data(internal_data(nullptr, 0)) {}
                  ^
1 error generated.

Solution

Compile with LLVM 3.5.1.

Install LLVM with Homebrew.

brew install llvm --with-clang --with-asan

On my MBA Core I7 building LLVM takes about 20 minutes.

Note: this formula does not overwrite the existing LLVM tools installed by Xcode. Instead, the formula is considerate enough to install the LLVM tools in /usr/local/opt/llvm/bin.

To build asyncplusplus:

export CC=/usr/local/opt/llvm/bin/clang
export CXX=/usr/local/opt/llvm/bin/clang++
mkdir build && cd build
cmake ..
make

Heap Error on Visual Studio 2013 Update 2

I know that Visual Studio compatibility is pretty "experimental" but my basic tests all work and that's great, and I am willing to improve.

While testing I think I've found a memory bug.

Offending code:

  // Create an event
    async::event_task<int> e, e1;
    auto t = e.get_task();
    async::shared_task<int> ev1 = e1.get_task().share();
    // Add a continuation to the task
    auto tasksChain1 = t.then([=](int val)
    {
        printf("Hello\n");
        return ev1;
    });

    // Set the event value, which will cause the continuation to run
    e.set(42);
    //e1.set(2);
    e1.cancel();
    printf("End of program\n");

Visual Studio breaks when closing the program (when CRT does basic checks on allocated memory)

HEAP[AsyncPlusPlusTest.exe]: HEAP: Free Heap block 3695e8 modified at 369640 after it was freed

Calling e1.set(...) instead of e1.cancel() fixes the problem, so probably the cancel(...) code path is triggering use of some pieces of already deleted memory.

In my experience Visual Studio debug memory manager does a good number of checks so if it says that there's a memory error, very likely the error is somewhere and very often doesn't show up on other compilers/platforms (The error doesn't show up on latest Clang OSX).

I will investigate exactly where is the problem but if the author has any idea/suggestion, it would help.

Change the name of the async namespace

Firstly, this is a terrific project. It does just what it says on the tin.

The async namespace that is used in this project is far too generic in my opinion and could lead to some confusion or the potential for clashes.

Could I propose changing the namespace to something like asyncpp ?

[feature] iterative when_all

Many code paths (dynamically/iteratively) generate tasks that need to be waited on.
Currently one needs to make a temporary storage for all of them and then create when_all composition.
The proposal api simply separates the when_all initialization and addition steps, allowing it to be easily used with loops, generators, fold expressions etc..

Please let me know if the feature is ok with you and any comments on proposed code below:
I can make a pr then..
// On a side note, while it should be possible to make an analogue for when_any, i dont imagine (many) use-cases for that rn. Therefore not suggesting to add it.

/// Returns when_all state that can be used with tasks from generators without intermediate storage
/// Use operator(task) to fill it with tasks and
/// readyTask is the composite result task
template<typename Ttask = async::task<void> >
auto when_all_iterative(size_t total_count)
{
    typedef typename std::decay<Ttask>::type task_type;
    typedef std::vector<task_type> result_type;

    struct when_all_iterative_state
    {
        typedef async::detail::when_all_state<result_type> state_type;

        void operator() (task_type&& source_task)
        {
            LIBASYNC_ASSERT(state, std::logic_error, "Adding to empty when_all");

            // Add a continuation to each task to add its result to the shared state
            // Last task sets the event result
            LIBASYNC_TRY {
                source_task.then(async::inline_scheduler(), async::detail::when_all_func_range<task_type, result_type>(next_index++, async::detail::ref_count_ptr<async::detail::when_all_state<result_type>>(state)));
            } LIBASYNC_CATCH(...) {
                // Make sure we don't leak memory if then() throws
                addFailed(1);
                LIBASYNC_RETHROW();
            }
        }

        void setTotal(size_t total_count)
        {
            LIBASYNC_ASSERT(!state, std::logic_error, "Initializing state twice");

            state = new state_type(total_count);
            state->result.resize(total_count);
            readyTask = state->event.get_task();
        }

        void addFailed(size_t failed = 1)
        {
            LIBASYNC_ASSERT(state, std::logic_error, "Adding to empty when_all");
            state->remove_ref(failed);
            next_index += failed;
        }

    protected:
        state_type* state = nullptr;
        size_t next_index = 0;
    public:
        async::task<result_type> readyTask = async::make_task<result_type>({});
    } state;

    if (total_count)
        state.setTotal(total_count);

    return state;
}

Failed to compile under linux

Wanted to experiment under linux but got this errors:

./build-static-gcc.sh 
In file included from include/async++.h:106:0,
                 from src/scheduler.cpp:31:
/usr/include/c++/4.7/type_traits: In substitution of ‘template<class _From1, class _To1> static decltype ((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one())) std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = _From1; _To1 = _To1; _From = const async::task_run_handle&; _To = async::task_run_handle] [with _From1 = const async::task_run_handle&; _To1 = async::task_run_handle]’:
/usr/include/c++/4.7/type_traits:1258:70:   required from ‘constexpr const bool std::__is_convertible_helper<const async::task_run_handle&, async::task_run_handle, false>::value’
/usr/include/c++/4.7/type_traits:1263:12:   required from ‘struct std::is_convertible<const async::task_run_handle&, async::task_run_handle>’
/usr/include/c++/4.7/type_traits:116:12:   required from ‘struct std::__and_<std::is_convertible<const async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>&, async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)> >, std::is_convertible<const async::task_run_handle&, async::task_run_handle> >’
/usr/include/c++/4.7/tuple:530:44:   required from ‘struct std::_Bind_simple<async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>(async::task_run_handle)>’
/usr/include/c++/4.7/thread:133:9:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>; _Args = {async::task_run_handle}]’
src/scheduler.cpp:454:18:   required from here
include/async++/scheduler.h:83:2: error: ‘async::task_run_handle::task_run_handle(const async::task_run_handle&)’ is private
In file included from /usr/include/c++/4.7/bits/move.h:57:0,
                 from /usr/include/c++/4.7/bits/stl_pair.h:61,
                 from /usr/include/c++/4.7/utility:72,
                 from /usr/include/c++/4.7/algorithm:61,
                 from src/scheduler.cpp:21:
/usr/include/c++/4.7/type_traits:1252:2: error: within this context
In file included from include/async++.h:106:0,
                 from src/scheduler.cpp:31:
/usr/include/c++/4.7/type_traits: In substitution of ‘template<class _From1, class _To1> static decltype ((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one())) std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = _From1; _To1 = _To1; _From = const async::task_run_handle&; _To = async::task_run_handle] [with _From1 = const async::task_run_handle&; _To1 = async::task_run_handle]’:
/usr/include/c++/4.7/type_traits:1258:70:   required from ‘constexpr const bool std::__is_convertible_helper<const async::task_run_handle&, async::task_run_handle, false>::value’
/usr/include/c++/4.7/type_traits:1263:12:   required from ‘struct std::is_convertible<const async::task_run_handle&, async::task_run_handle>’
/usr/include/c++/4.7/type_traits:116:12:   required from ‘struct std::__and_<std::is_convertible<const async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>&, async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)> >, std::is_convertible<const async::task_run_handle&, async::task_run_handle> >’
/usr/include/c++/4.7/tuple:530:44:   required from ‘struct std::_Bind_simple<async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>(async::task_run_handle)>’
/usr/include/c++/4.7/thread:133:9:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>; _Args = {async::task_run_handle}]’
src/scheduler.cpp:454:18:   required from here
include/async++/scheduler.h:83:2: error: ‘async::task_run_handle::task_run_handle(const async::task_run_handle&)’ is private
In file included from /usr/include/c++/4.7/bits/move.h:57:0,
                 from /usr/include/c++/4.7/bits/stl_pair.h:61,
                 from /usr/include/c++/4.7/utility:72,
                 from /usr/include/c++/4.7/algorithm:61,
                 from src/scheduler.cpp:21:
/usr/include/c++/4.7/type_traits:1252:2: error: within this context
In file included from include/async++.h:106:0,
                 from src/scheduler.cpp:31:
/usr/include/c++/4.7/type_traits: In instantiation of ‘constexpr const bool std::__is_convertible_helper<const async::task_run_handle&, async::task_run_handle, false>::value’:
/usr/include/c++/4.7/type_traits:1263:12:   required from ‘struct std::is_convertible<const async::task_run_handle&, async::task_run_handle>’
/usr/include/c++/4.7/type_traits:116:12:   required from ‘struct std::__and_<std::is_convertible<const async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>&, async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)> >, std::is_convertible<const async::task_run_handle&, async::task_run_handle> >’
/usr/include/c++/4.7/tuple:530:44:   required from ‘struct std::_Bind_simple<async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>(async::task_run_handle)>’
/usr/include/c++/4.7/thread:133:9:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = async::detail::thread_scheduler_impl::schedule(async::task_run_handle)::<lambda(async::task_run_handle)>; _Args = {async::task_run_handle}]’
src/scheduler.cpp:454:18:   required from here
include/async++/scheduler.h:83:2: error: ‘async::task_run_handle::task_run_handle(const async::task_run_handle&)’ is private
In file included from /usr/include/c++/4.7/bits/move.h:57:0,
                 from /usr/include/c++/4.7/bits/stl_pair.h:61,
                 from /usr/include/c++/4.7/utility:72,
                 from /usr/include/c++/4.7/algorithm:61,
                 from src/scheduler.cpp:21:
/usr/include/c++/4.7/type_traits:1258:70: error: within this context
ar: scheduler.o: No such file or directory

gcc (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3

Compilation failures in C++20 due to removal of std::result_of

I'm using asyncplusplus from a C++20 project and it's failing to compile because std::result_of was removed in C++20. I worked around this problem by replacing std::result_of with std::invoke_result in my fork. You can see the changes here: https://github.com/IanLilleyT/asyncplusplus/commit/1a9cbc504eb675e42524c44f9ecf46973574b257. I opened an issue instead of a PR because I'm not sure if this library wants to include C++17 code in its headers, even if it's behind a macro. Let me know if I should turn this into a PR or not.

The cmake code / comment is partly taken from: https://stackoverflow.com/a/60890947

Thanks for reading!

msvc 2017 build

I tried building async++ with msvc 2017 and did not succeed, am I doing something wrong?

C:\workspace\asyncplusplus\build>cmake .. -G "Visual Studio 15 Win64"
-- The C compiler identification is MSVC 19.10.25019.0
-- The CXX compiler identification is MSVC 19.10.25019.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/bin/HostX86/x64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: C:/workspace/asyncplusplus/build

C:\workspace\asyncplusplus\build>cmake --build . --target ALL_BUILD --config Release
Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 4/8/2017 3:03:05 PM.
Project "C:\workspace\asyncplusplus\build\ALL_BUILD.vcxproj" on node 1 (default targets).
Project "C:\workspace\asyncplusplus\build\ALL_BUILD.vcxproj" (1) is building "C:\workspace\asyncplusplus\build\ZERO_CHE
CK.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
Creating directory "x64\Release\ZERO_CHECK".
Creating directory "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog".
InitializeBuildStatus:
Creating "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
Checking Build System
CMake does not need to re-run because C:/workspace/asyncplusplus/build/CMakeFiles/generate.stamp is up-to-date.
FinalizeBuildStatus:
Deleting file "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild".
Touching "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\ZERO_CHECK.lastbuildstate".
Done Building Project "C:\workspace\asyncplusplus\build\ZERO_CHECK.vcxproj" (default targets).

Project "C:\workspace\asyncplusplus\build\ALL_BUILD.vcxproj" (1) is building "C:\workspace\asyncplusplus\build\Async++.
vcxproj" (3) on node 1 (default targets).
PrepareForBuild:
Creating directory "Async++.dir\Release".
Creating directory "C:\workspace\asyncplusplus\build\Release".
Creating directory "Async++.dir\Release\Async++.tlog".
InitializeBuildStatus:
Creating "Async++.dir\Release\Async++.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
Building Custom Rule C:/workspace/asyncplusplus/CMakeLists.txt
CMake does not need to re-run because C:\workspace\asyncplusplus\build\CMakeFiles\generate.stamp is up-to-date.
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\CL.exe /c /IC
:\workspace\asyncplusplus\include /nologo /W3 /WX- /diagnostics:classic /O2 /Ob2 /D WIN32 /D _WINDOWS /D NDEBUG /D "C
MAKE_INTDIR="Release"" /D LIBASYNC_BUILD /D _WINDLL /D _MBCS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScop
e /Zc:inline /GR- /Fo"Async++.dir\Release\" /Fd"Async++.dir\Release\vc141.pdb" /Gd /TP /errorReport:queue C:\workspa
ce\asyncplusplus\src\scheduler.cpp C:\workspace\asyncplusplus\src\threadpool_scheduler.cpp
scheduler.cpp
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2146: syntax error: missing ';' before id
entifier 'tmp' [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2275: 'async::detail::task_ptr': illegal
use of this type as an expression [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/scheduler_fwd.h(58): note: see declaration of 'async::detail::task_ptr'
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2065: 'i': undeclared identifier [C:\work
space\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C3861: 'tmp': identifier not found [C:\wor
kspace\asyncplusplus\build\Async++.vcxproj]
threadpool_scheduler.cpp
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2146: syntax error: missing ';' before id
entifier 'tmp' [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2275: 'async::detail::task_ptr': illegal
use of this type as an expression [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/scheduler_fwd.h(58): note: see declaration of 'async::detail::task_ptr'
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2065: 'i': undeclared identifier [C:\work
space\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C3861: 'tmp': identifier not found [C:\wor
kspace\asyncplusplus\build\Async++.vcxproj]
Generating Code...
Done Building Project "C:\workspace\asyncplusplus\build\Async++.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\workspace\asyncplusplus\build\ALL_BUILD.vcxproj" (default targets) -- FAILED.

Build FAILED.

"C:\workspace\asyncplusplus\build\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\workspace\asyncplusplus\build\Async++.vcxproj" (default target) (3) ->
(ClCompile target) ->
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2146: syntax error: missing ';' before
identifier 'tmp' [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2275: 'async::detail::task_ptr': illega
l use of this type as an expression [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2065: 'i': undeclared identifier [C:\wo
rkspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C3861: 'tmp': identifier not found [C:\w
orkspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2146: syntax error: missing ';' before
identifier 'tmp' [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2275: 'async::detail::task_ptr': illega
l use of this type as an expression [C:\workspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C2065: 'i': undeclared identifier [C:\wo
rkspace\asyncplusplus\build\Async++.vcxproj]
c:\workspace\asyncplusplus\include\async++/continuation_vector.h(135): error C3861: 'tmp': identifier not found [C:\w
orkspace\asyncplusplus\build\Async++.vcxproj]

0 Warning(s)
8 Error(s)

Time Elapsed 00:00:04.54

Make a release

Hi! Thank you for the library!

As far as I see since the last library release you've have a lot of useful commits. Can you please make one more release? It helps a lot with packaging your library into dependency managers like Conan.

Thank you.

Update / simplify + cmake

I really like what you have done here. Do you plan on updating it since many compilers now support C++11? There are also other enhancements that might be nice to add such as Travis-CI, cmake, and unit testing.

I forked the project and I was able to get it to compile on Mac OS X using cmake but when I ran it on Travis it bombed. I looked at the code and there was a lot I didn't understand. I can however refork if you like and merge in / show you my changes.

Mostly I'm just curious to find out what you are planning for the project if anything.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.