diff --git a/CMakeLists.txt b/CMakeLists.txt index 19d977b..f05fabd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required( VERSION 3.0 ) project( tasks ) -set( LIB_VERSION "1.2.5" ) -set( SO_VERSION "1.1.0" ) +set( LIB_VERSION "1.2.6" ) +set( SO_VERSION "2.0.0" ) add_definitions( -Wextra -Wall -pedantic ) diff --git a/README.md b/README.md index cb96b2b..b582446 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Task::future& foo = bar() ; int r = foo.await() ; ``` -**3. Example use an alternative use of .await() method of a future.** +**3. Example use of an alternative .await() method of a future.** ```c++ @@ -131,42 +131,43 @@ Task::future& foo = Task::run( foo ) ; ``` -**3. Creating a future that combines multiple functions. .get() and .queue() on the future will cause passed in functions to run sequentially and in the order they are specified. .await() and .then() will cause passed in functions to run concurrently.** +**3. Creating a future that combines arbitrary number of functions. .get() and .queue() on the future will cause passed in functions to run sequentially and in the order they are specified. .await() and .then() will cause passed in functions to run concurrently.** ```c++ void foo() ; //function prototype void bar() ; //function prototype +void woof() ; //function prototype -Task::future& foo = Task::run( foo,bar ) ; +Task::future& foo = Task::run( foo,bar,woof ) ; ``` -**4. Creating a future that combines multiple tasks and their continuations that take no argument. .get() and .queue() on the future will cause passed in functions to run sequentially and in the order they are specified. .await() and .then() will cause passed in functions to run concurrently.** +**4. Creating a future that combines arbitrary number of tasks and their continuations that take no argument. .get() and .queue() on the future will cause passed in functions to run sequentially and in the order they are specified. .await() and .then() will cause passed in functions to run concurrently.** ```c++ void foo() ; //function prototype void bar() ; //function prototype -void cfoo() ; //function prototype -void cbar() ; //function prototype +void cfoo() ; //continuation function prototype +void cbar() ; //continuation function prototype -Task::future& e = Task::run( Task::void_pair{ foo,cfoo },Task::void_pair{ bar,cbar } ) ; +Task::future& e = Task::run( Task::make_pair( foo,cfoo ),Task::make_pair( bar,cbar ) ) ; ``` -**5. Creating a future that combines multiple tasks and their continuations that takes an argument. .get() and .queue() on the future will cause passed in pairs to run sequentially and in the order they are specified. .await() and .then() will cause passed in pairs to run concurrently. The result of the future is undefined and a function that takes no argument should be used if .await() method of the future is called.** +**5. Creating a future that combines arbitrary number of tasks and their continuations that takes an argument. .get() and .queue() on the future will cause passed in pairs to run sequentially and in the order they are specified. .await() and .then() will cause passed in pairs to run concurrently. The result of the future is undefined and a function that takes no argument should be used if .await() method of the future is called.** ```c++ int foo() ; //function prototype int bar() ; //function prototype -void cfoo( int ) ; //function prototype -void cbar( int ) ; //function prototype +void cfoo( int ) ; //continuation function prototype +void cbar( int ) ; //continuation function prototype -Task::future& e = Task::run( Task::pair{ foo,cfoo },Task::pair{ bar,cbar } ) ; +Task::future& e = Task::run( Task::make_pair( foo,cfoo ),Task::make_pair( bar,cbar ) ) ; ``` Further documentation of how to use the library is here[1] and here[2]. diff --git a/example.cpp b/example.cpp index abbc8bb..bab2c8c 100644 --- a/example.cpp +++ b/example.cpp @@ -201,9 +201,9 @@ static void _testing_multiple_tasks() auto ra2 = [](){ _print( "r2" ) ; } ; auto ra3 = [](){ _print( "r3" ) ; } ; - Task::future& e = Task::run( Task::void_pair{ fna1,ra1 }, - Task::void_pair{ fna2,ra2 }, - Task::void_pair{ fna3,ra3 } ) ; + Task::future& e = Task::run( Task::make_pair( fna1,ra1 ), + Task::make_pair( fna2,ra2 ), + Task::make_pair( fna3,ra3 ) ) ; e.await() ; @@ -217,9 +217,9 @@ static void _testing_multiple_tasks() auto r2 = []( int ){ _print( "r2" ) ; } ; auto r3 = []( int ){ _print( "r3" ) ; } ; - Task::future& s = Task::run( Task::pair{ fn1,r1 }, - Task::pair{ fn2,r2 }, - Task::pair{ fn3,r3 } ) ; + Task::future& s = Task::run( Task::make_pair( fn1,r1 ), + Task::make_pair( fn2,r2 ), + Task::make_pair( fn3,r3 ) ) ; s.then( _testing_multiple_tasks_with_start ) ; } @@ -263,9 +263,9 @@ static void _testing_multiple_tasks_with_start() auto r2 = [ = ]( int ){ _print( "r2" ) ; e->count() ; } ; auto r3 = [ = ]( int ){ _print( "r3" ) ; e->count() ; } ; - Task::future& s = Task::run( Task::pair{ fn1,r1 }, - Task::pair{ fn2,r2 }, - Task::pair{ fn3,r3 } ) ; + Task::future& s = Task::run( Task::make_pair( fn1,r1 ), + Task::make_pair( fn2,r2 ), + Task::make_pair( fn3,r3 ) ) ; s.start() ; } @@ -282,9 +282,9 @@ static void _testing_queue_with_no_results() auto ra2 = [](){ _print( "r2" ) ; } ; auto ra3 = [](){ _print( "r3" ) ; } ; - Task::future& e = Task::run( Task::void_pair{ fna1,ra1 }, - Task::void_pair{ fna2,ra2 }, - Task::void_pair{ fna3,ra3 } ) ; + Task::future& e = Task::run( Task::make_pair( fna1,ra1 ), + Task::make_pair( fna2,ra2 ), + Task::make_pair( fna3,ra3 ) ) ; e.queue( _testing_queue_with_results ) ; } @@ -301,9 +301,9 @@ static void _testing_queue_with_results() auto r2 = [ = ]( int ){ _print( "r2" ) ; } ; auto r3 = [ = ]( int ){ _print( "r3" ) ; } ; - Task::future& s = Task::run( Task::pair{ fn1,r1 }, - Task::pair{ fn2,r2 }, - Task::pair{ fn3,r3 } ) ; + Task::future& s = Task::run( Task::make_pair( fn1,r1 ), + Task::make_pair( fn2,r2 ), + Task::make_pair( fn3,r3 ) ) ; s.queue( _test_run_then ) ; } diff --git a/task.hpp b/task.hpp index 93020c1..47c0aef 100644 --- a/task.hpp +++ b/task.hpp @@ -1,5 +1,5 @@ /* - * copyright: 2014-2017 + * copyright: 2014-2018 * name : Francis Banyikwa * email: mhogomchungu@gmail.com * @@ -106,11 +106,6 @@ namespace Task { - template< typename T > - using pair = std::pair< std::function< T() >,std::function< void( T ) > > ; - - using void_pair = std::pair< std::function< void() >,std::function< void() > > ; - template< typename T > class future; @@ -122,6 +117,37 @@ namespace Task void add( Task::future< T >&,Task::future< T >&,std::function< void( T ) >&& ) ; } + template< typename T > + struct pair{ + pair( std::function< T() > first,std::function< void( T ) > second ) : + value( std::make_pair( std::move( first ),std::move( second ) ) ) + { + } + std::pair< std::function< T() >,std::function< void( T ) > > value ; + }; + + template<> + struct pair{ + pair( std::function< void() > first,std::function< void() > second ) : + value( std::make_pair( std::move( first ),std::move( second ) ) ) + { + } + std::pair< std::function< void() >,std::function< void() > > value ; + }; + + template< typename E,typename F > + pair::type> make_pair( E e,F f ) + { + return pair::type>( std::move( e ),std::move( f ) ) ; + } + + template< typename E,typename F, + typename std::enable_if::type>::value>::type> + pair< void > make_pair( E e,F f ) + { + return pair< void >( std::move( e ),std::move( f ) ) ; + } + class Thread : public QThread { Q_OBJECT @@ -350,7 +376,7 @@ namespace Task }; template<> - class future< void > : private QObject + class future< void > : private QObject { public: void then( std::function< void() > function ) @@ -653,14 +679,14 @@ namespace Task template< typename E,typename F,typename ... T > void add_pair( Task::future< E >& f,F&& s,T&& ... t ) { - add( f,Task::detail::run( std::move( s.first ) ),std::move( s.second ) ) ; + add( f,Task::detail::run( std::move( s.value.first ) ),std::move( s.value.second ) ) ; add_pair( f,std::forward( t ) ... ) ; } template< typename F,typename ... T > void add_pair_void( Task::future< void >& f,F&& s,T&& ... t ) { - add_void( f,Task::detail::run( std::move( s.first ) ),std::move( s.second ) ) ; + add_void( f,Task::detail::run( std::move( s.value.first ) ),std::move( s.value.second ) ) ; add_pair_void( f,std::forward( t ) ... ) ; } @@ -705,7 +731,7 @@ namespace Task } template< typename ... T > - Task::future< void >& run( void_pair s,T ... t ) + Task::future< void >& run( pair< void > s,T ... t ) { auto& e = Task::detail::future< void >() ; Task::detail::add_pair_void( e,std::move( s ),std::move( t ) ... ) ; @@ -1032,27 +1058,27 @@ auto ra1 = [](){ std::cout << "r1" << std::endl ; } ; auto ra2 = [](){ std::cout << "r2" << std::endl ; } ; auto ra3 = [](){ std::cout << "r3" << std::endl ; } ; -Task::future& e = Task::run( Task::void_pair{ fna1,ra1 }, - Task::void_pair{ fna2,ra2 }, - Task::void_pair{ fna3,ra3 } ) ; +Task::future& e = Task::run( Task::make_pair( fna1,ra1 ), + Task::make_pair( fna2,ra2 ), + Task::make_pair( fna3,ra3 ) ) ; e.await() ; std::cout<< "Testing multiple tasks with continuation arguments" << std::endl ; -auto fn1 = [](){ _printThreadID(); return 0 ;} ; -auto fn2 = [](){ _printThreadID(); return 0 ;} ; +auto fn1 = [](){ _printThreadID(); return 0 ; } ; +auto fn2 = [](){ _printThreadID(); return 0 ; } ; auto fn3 = [](){ _printThreadID(); return 0 ; } ; auto r1 = []( int ){ std::cout << "r1" << std::endl ; } ; auto r2 = []( int ){ std::cout << "r2" << std::endl ; } ; auto r3 = []( int ){ std::cout << "r3" << std::endl ; } ; -Task::future& s = Task::run( Task::pair{ fn1,r1 }, - Task::pair{ fn2,r2 }, - Task::pair{ fn3,r3 } ) ; +Task::future& s = Task::run( Task::make_pair( fn1,r1 ), + Task::make_pair( fn2,r2 ), + Task::make_pair( fn3,r3 ) ) ; -s.then( [](){ QCoreApplication::quit() ;} ) ; +s.then( [](){ QCoreApplication::quit() ; } ) ; #endif //end example block