Initial commit: Final state of the master project
This commit is contained in:
476
Research/inc/tbb/compat/condition_variable
Normal file
476
Research/inc/tbb/compat/condition_variable
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
Copyright 2005-2015 Intel Corporation. All Rights Reserved.
|
||||
|
||||
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
|
||||
you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation. Threading Building Blocks is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details. You should have received a copy of
|
||||
the GNU General Public License along with Threading Building Blocks; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
As a special exception, you may use this file as part of a free software library without
|
||||
restriction. Specifically, if other files instantiate templates or use macros or inline
|
||||
functions from this file, or you compile this file and link it with other files to produce
|
||||
an executable, this file does not by itself cause the resulting executable to be covered
|
||||
by the GNU General Public License. This exception does not however invalidate any other
|
||||
reasons why the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef __TBB_condition_variable_H
|
||||
#define __TBB_condition_variable_H
|
||||
|
||||
#if _WIN32||_WIN64
|
||||
#include "../machine/windows_api.h"
|
||||
|
||||
namespace tbb {
|
||||
namespace interface5 {
|
||||
namespace internal {
|
||||
struct condition_variable_using_event
|
||||
{
|
||||
//! Event for blocking waiting threads.
|
||||
HANDLE event;
|
||||
//! Protects invariants involving n_waiters, release_count, and epoch.
|
||||
CRITICAL_SECTION mutex;
|
||||
//! Number of threads waiting on this condition variable
|
||||
int n_waiters;
|
||||
//! Number of threads remaining that should no longer wait on this condition variable.
|
||||
int release_count;
|
||||
//! To keep threads from waking up prematurely with earlier signals.
|
||||
unsigned epoch;
|
||||
};
|
||||
}}} // namespace tbb::interface5::internal
|
||||
|
||||
#ifndef CONDITION_VARIABLE_INIT
|
||||
typedef void* CONDITION_VARIABLE;
|
||||
typedef CONDITION_VARIABLE* PCONDITION_VARIABLE;
|
||||
#endif
|
||||
|
||||
#else /* if not _WIN32||_WIN64 */
|
||||
#include <errno.h> // some systems need it for ETIMEDOUT
|
||||
#include <pthread.h>
|
||||
#if __linux__
|
||||
#include <ctime>
|
||||
#else /* generic Unix */
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#endif /* _WIN32||_WIN64 */
|
||||
|
||||
#include "../tbb_stddef.h"
|
||||
#include "../mutex.h"
|
||||
#include "../tbb_thread.h"
|
||||
#include "../tbb_exception.h"
|
||||
#include "../tbb_profiling.h"
|
||||
|
||||
namespace tbb {
|
||||
|
||||
namespace interface5 {
|
||||
|
||||
// C++0x standard working draft 30.4.3
|
||||
// Lock tag types
|
||||
struct defer_lock_t { }; //! do not acquire ownership of the mutex
|
||||
struct try_to_lock_t { }; //! try to acquire ownership of the mutex without blocking
|
||||
struct adopt_lock_t { }; //! assume the calling thread has already
|
||||
const defer_lock_t defer_lock = {};
|
||||
const try_to_lock_t try_to_lock = {};
|
||||
const adopt_lock_t adopt_lock = {};
|
||||
|
||||
// C++0x standard working draft 30.4.3.1
|
||||
//! lock_guard
|
||||
template<typename M>
|
||||
class lock_guard : tbb::internal::no_copy {
|
||||
public:
|
||||
//! mutex type
|
||||
typedef M mutex_type;
|
||||
|
||||
//! Constructor
|
||||
/** precondition: If mutex_type is not a recursive mutex, the calling thread
|
||||
does not own the mutex m. */
|
||||
explicit lock_guard(mutex_type& m) : pm(m) {m.lock();}
|
||||
|
||||
//! Adopt_lock constructor
|
||||
/** precondition: the calling thread owns the mutex m. */
|
||||
lock_guard(mutex_type& m, adopt_lock_t) : pm(m) {}
|
||||
|
||||
//! Destructor
|
||||
~lock_guard() { pm.unlock(); }
|
||||
private:
|
||||
mutex_type& pm;
|
||||
};
|
||||
|
||||
// C++0x standard working draft 30.4.3.2
|
||||
//! unique_lock
|
||||
template<typename M>
|
||||
class unique_lock : tbb::internal::no_copy {
|
||||
friend class condition_variable;
|
||||
public:
|
||||
typedef M mutex_type;
|
||||
|
||||
// 30.4.3.2.1 construct/copy/destroy
|
||||
// NB: Without constructors that take an r-value reference to a unique_lock, the following constructor is of little use.
|
||||
//! Constructor
|
||||
/** postcondition: pm==0 && owns==false */
|
||||
unique_lock() : pm(NULL), owns(false) {}
|
||||
|
||||
//! Constructor
|
||||
/** precondition: if mutex_type is not a recursive mutex, the calling thread
|
||||
does not own the mutex m. If the precondition is not met, a deadlock occurs.
|
||||
postcondition: pm==&m and owns==true */
|
||||
explicit unique_lock(mutex_type& m) : pm(&m) {m.lock(); owns=true;}
|
||||
|
||||
//! Defer_lock constructor
|
||||
/** postcondition: pm==&m and owns==false */
|
||||
unique_lock(mutex_type& m, defer_lock_t) : pm(&m), owns(false) {}
|
||||
|
||||
//! Try_to_lock constructor
|
||||
/** precondition: if mutex_type is not a recursive mutex, the calling thread
|
||||
does not own the mutex m. If the precondition is not met, a deadlock occurs.
|
||||
postcondition: pm==&m and owns==res where res is the value returned by
|
||||
the call to m.try_lock(). */
|
||||
unique_lock(mutex_type& m, try_to_lock_t) : pm(&m) {owns = m.try_lock();}
|
||||
|
||||
//! Adopt_lock constructor
|
||||
/** precondition: the calling thread owns the mutex. If it does not, mutex->unlock() would fail.
|
||||
postcondition: pm==&m and owns==true */
|
||||
unique_lock(mutex_type& m, adopt_lock_t) : pm(&m), owns(true) {}
|
||||
|
||||
//! Timed unique_lock acquisition.
|
||||
/** To avoid requiring support for namespace chrono, this method deviates from the working draft in that
|
||||
it uses tbb::tick_count::interval_t to specify the time duration. */
|
||||
unique_lock(mutex_type& m, const tick_count::interval_t &i) : pm(&m) {owns = try_lock_for( i );}
|
||||
|
||||
#if __TBB_CPP11_RVALUE_REF_PRESENT
|
||||
//! Move constructor
|
||||
/** postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this
|
||||
construction), src.pm == 0 and src.owns == false. */
|
||||
unique_lock(unique_lock && src): pm(NULL), owns(false) {this->swap(src);}
|
||||
|
||||
//! Move assignment
|
||||
/** effects: If owns calls pm->unlock().
|
||||
Postconditions: pm == src_p.pm and owns == src_p.owns (where src_p is the state of src just prior to this
|
||||
assignment), src.pm == 0 and src.owns == false. */
|
||||
unique_lock& operator=(unique_lock && src) {
|
||||
if (owns)
|
||||
this->unlock();
|
||||
pm = NULL;
|
||||
this->swap(src);
|
||||
return *this;
|
||||
}
|
||||
#endif // __TBB_CPP11_RVALUE_REF_PRESENT
|
||||
|
||||
//! Destructor
|
||||
~unique_lock() { if( owns ) pm->unlock(); }
|
||||
|
||||
// 30.4.3.2.2 locking
|
||||
//! Lock the mutex and own it.
|
||||
void lock() {
|
||||
if( pm ) {
|
||||
if( !owns ) {
|
||||
pm->lock();
|
||||
owns = true;
|
||||
} else
|
||||
throw_exception_v4( tbb::internal::eid_possible_deadlock );
|
||||
} else
|
||||
throw_exception_v4( tbb::internal::eid_operation_not_permitted );
|
||||
__TBB_ASSERT( owns, NULL );
|
||||
}
|
||||
|
||||
//! Try to lock the mutex.
|
||||
/** If successful, note that this lock owns it. Otherwise, set it false. */
|
||||
bool try_lock() {
|
||||
if( pm ) {
|
||||
if( !owns )
|
||||
owns = pm->try_lock();
|
||||
else
|
||||
throw_exception_v4( tbb::internal::eid_possible_deadlock );
|
||||
} else
|
||||
throw_exception_v4( tbb::internal::eid_operation_not_permitted );
|
||||
return owns;
|
||||
}
|
||||
|
||||
//! Try to lock the mutex.
|
||||
bool try_lock_for( const tick_count::interval_t &i );
|
||||
|
||||
//! Unlock the mutex
|
||||
/** And note that this lock no longer owns it. */
|
||||
void unlock() {
|
||||
if( owns ) {
|
||||
pm->unlock();
|
||||
owns = false;
|
||||
} else
|
||||
throw_exception_v4( tbb::internal::eid_operation_not_permitted );
|
||||
__TBB_ASSERT( !owns, NULL );
|
||||
}
|
||||
|
||||
// 30.4.3.2.3 modifiers
|
||||
//! Swap the two unique locks
|
||||
void swap(unique_lock& u) {
|
||||
mutex_type* t_pm = u.pm; u.pm = pm; pm = t_pm;
|
||||
bool t_owns = u.owns; u.owns = owns; owns = t_owns;
|
||||
}
|
||||
|
||||
//! Release control over the mutex.
|
||||
mutex_type* release() {
|
||||
mutex_type* o_pm = pm;
|
||||
pm = NULL;
|
||||
owns = false;
|
||||
return o_pm;
|
||||
}
|
||||
|
||||
// 30.4.3.2.4 observers
|
||||
//! Does this lock own the mutex?
|
||||
bool owns_lock() const { return owns; }
|
||||
|
||||
// TODO: Un-comment 'explicit' when the last non-C++0x compiler support is dropped
|
||||
//! Does this lock own the mutex?
|
||||
/*explicit*/ operator bool() const { return owns; }
|
||||
|
||||
//! Return the mutex that this lock currently has.
|
||||
mutex_type* mutex() const { return pm; }
|
||||
|
||||
private:
|
||||
mutex_type* pm;
|
||||
bool owns;
|
||||
};
|
||||
|
||||
template<typename M>
|
||||
bool unique_lock<M>::try_lock_for( const tick_count::interval_t &i)
|
||||
{
|
||||
const int unique_lock_tick = 100; /* microseconds; 0.1 milliseconds */
|
||||
// the smallest wait-time is 0.1 milliseconds.
|
||||
bool res = pm->try_lock();
|
||||
int duration_in_micro;
|
||||
if( !res && (duration_in_micro=int(i.seconds()*1e6))>unique_lock_tick ) {
|
||||
tick_count::interval_t i_100( double(unique_lock_tick)/1e6 /* seconds */); // 100 microseconds = 0.1*10E-3
|
||||
do {
|
||||
this_tbb_thread::sleep(i_100); // sleep for 100 micro seconds
|
||||
duration_in_micro -= unique_lock_tick;
|
||||
res = pm->try_lock();
|
||||
} while( !res && duration_in_micro>unique_lock_tick );
|
||||
}
|
||||
return (owns=res);
|
||||
}
|
||||
|
||||
//! Swap the two unique locks that have the mutexes of same type
|
||||
template<typename M>
|
||||
void swap(unique_lock<M>& x, unique_lock<M>& y) { x.swap( y ); }
|
||||
|
||||
namespace internal {
|
||||
|
||||
#if _WIN32||_WIN64
|
||||
union condvar_impl_t {
|
||||
condition_variable_using_event cv_event;
|
||||
CONDITION_VARIABLE cv_native;
|
||||
};
|
||||
void __TBB_EXPORTED_FUNC internal_initialize_condition_variable( condvar_impl_t& cv );
|
||||
void __TBB_EXPORTED_FUNC internal_destroy_condition_variable( condvar_impl_t& cv );
|
||||
void __TBB_EXPORTED_FUNC internal_condition_variable_notify_one( condvar_impl_t& cv );
|
||||
void __TBB_EXPORTED_FUNC internal_condition_variable_notify_all( condvar_impl_t& cv );
|
||||
bool __TBB_EXPORTED_FUNC internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx, const tick_count::interval_t* i = NULL );
|
||||
|
||||
#else /* if !(_WIN32||_WIN64), i.e., POSIX threads */
|
||||
typedef pthread_cond_t condvar_impl_t;
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
|
||||
//! cv_status
|
||||
/** C++0x standard working draft 30.5 */
|
||||
enum cv_status { no_timeout, timeout };
|
||||
|
||||
//! condition variable
|
||||
/** C++0x standard working draft 30.5.1
|
||||
@ingroup synchronization */
|
||||
class condition_variable : tbb::internal::no_copy {
|
||||
public:
|
||||
//! Constructor
|
||||
condition_variable() {
|
||||
#if _WIN32||_WIN64
|
||||
internal_initialize_condition_variable( my_cv );
|
||||
#else
|
||||
pthread_cond_init( &my_cv, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~condition_variable() {
|
||||
//precondition: There shall be no thread blocked on *this.
|
||||
#if _WIN32||_WIN64
|
||||
internal_destroy_condition_variable( my_cv );
|
||||
#else
|
||||
pthread_cond_destroy( &my_cv );
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Notify one thread and wake it up
|
||||
void notify_one() {
|
||||
#if _WIN32||_WIN64
|
||||
internal_condition_variable_notify_one( my_cv );
|
||||
#else
|
||||
pthread_cond_signal( &my_cv );
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Notify all threads
|
||||
void notify_all() {
|
||||
#if _WIN32||_WIN64
|
||||
internal_condition_variable_notify_all( my_cv );
|
||||
#else
|
||||
pthread_cond_broadcast( &my_cv );
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Release the mutex associated with the lock and wait on this condition variable
|
||||
void wait(unique_lock<mutex>& lock);
|
||||
|
||||
//! Wait on this condition variable while pred is false
|
||||
template <class Predicate>
|
||||
void wait(unique_lock<mutex>& lock, Predicate pred) {
|
||||
while( !pred() )
|
||||
wait( lock );
|
||||
}
|
||||
|
||||
//! Timed version of wait()
|
||||
cv_status wait_for(unique_lock<mutex>& lock, const tick_count::interval_t &i );
|
||||
|
||||
//! Timed version of the predicated wait
|
||||
/** The loop terminates when pred() returns true or when the time duration specified by rel_time (i) has elapsed. */
|
||||
template<typename Predicate>
|
||||
bool wait_for(unique_lock<mutex>& lock, const tick_count::interval_t &i, Predicate pred)
|
||||
{
|
||||
while( !pred() ) {
|
||||
cv_status st = wait_for( lock, i );
|
||||
if( st==timeout )
|
||||
return pred();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// C++0x standard working draft. 30.2.3
|
||||
typedef internal::condvar_impl_t* native_handle_type;
|
||||
|
||||
native_handle_type native_handle() { return (native_handle_type) &my_cv; }
|
||||
|
||||
private:
|
||||
internal::condvar_impl_t my_cv;
|
||||
};
|
||||
|
||||
|
||||
#if _WIN32||_WIN64
|
||||
inline void condition_variable::wait( unique_lock<mutex>& lock )
|
||||
{
|
||||
__TBB_ASSERT( lock.owns, NULL );
|
||||
lock.owns = false;
|
||||
if( !internal_condition_variable_wait( my_cv, lock.mutex() ) ) {
|
||||
int ec = GetLastError();
|
||||
// on Windows 7, SleepConditionVariableCS() may return ERROR_TIMEOUT while the doc says it returns WAIT_TIMEOUT
|
||||
__TBB_ASSERT_EX( ec!=WAIT_TIMEOUT&&ec!=ERROR_TIMEOUT, NULL );
|
||||
lock.owns = true;
|
||||
throw_exception_v4( tbb::internal::eid_condvar_wait_failed );
|
||||
}
|
||||
lock.owns = true;
|
||||
}
|
||||
|
||||
inline cv_status condition_variable::wait_for( unique_lock<mutex>& lock, const tick_count::interval_t& i )
|
||||
{
|
||||
cv_status rc = no_timeout;
|
||||
__TBB_ASSERT( lock.owns, NULL );
|
||||
lock.owns = false;
|
||||
// condvar_wait could be SleepConditionVariableCS (or SleepConditionVariableSRW) or our own pre-vista cond_var_wait()
|
||||
if( !internal_condition_variable_wait( my_cv, lock.mutex(), &i ) ) {
|
||||
int ec = GetLastError();
|
||||
if( ec==WAIT_TIMEOUT || ec==ERROR_TIMEOUT )
|
||||
rc = timeout;
|
||||
else {
|
||||
lock.owns = true;
|
||||
throw_exception_v4( tbb::internal::eid_condvar_wait_failed );
|
||||
}
|
||||
}
|
||||
lock.owns = true;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#else /* !(_WIN32||_WIN64) */
|
||||
inline void condition_variable::wait( unique_lock<mutex>& lock )
|
||||
{
|
||||
__TBB_ASSERT( lock.owns, NULL );
|
||||
lock.owns = false;
|
||||
if( pthread_cond_wait( &my_cv, lock.mutex()->native_handle() ) ) {
|
||||
lock.owns = true;
|
||||
throw_exception_v4( tbb::internal::eid_condvar_wait_failed );
|
||||
}
|
||||
// upon successful return, the mutex has been locked and is owned by the calling thread.
|
||||
lock.owns = true;
|
||||
}
|
||||
|
||||
inline cv_status condition_variable::wait_for( unique_lock<mutex>& lock, const tick_count::interval_t& i )
|
||||
{
|
||||
#if __linux__
|
||||
struct timespec req;
|
||||
double sec = i.seconds();
|
||||
clock_gettime( CLOCK_REALTIME, &req );
|
||||
req.tv_sec += static_cast<long>(sec);
|
||||
req.tv_nsec += static_cast<long>( (sec - static_cast<long>(sec))*1e9 );
|
||||
#else /* generic Unix */
|
||||
struct timeval tv;
|
||||
struct timespec req;
|
||||
double sec = i.seconds();
|
||||
int status = gettimeofday(&tv, NULL);
|
||||
__TBB_ASSERT_EX( status==0, "gettimeofday failed" );
|
||||
req.tv_sec = tv.tv_sec + static_cast<long>(sec);
|
||||
req.tv_nsec = tv.tv_usec*1000 + static_cast<long>( (sec - static_cast<long>(sec))*1e9 );
|
||||
#endif /*(choice of OS) */
|
||||
if( req.tv_nsec>=1e9 ) {
|
||||
req.tv_sec += 1;
|
||||
req.tv_nsec -= static_cast<long int>(1e9);
|
||||
}
|
||||
__TBB_ASSERT( 0<=req.tv_nsec && req.tv_nsec<1e9, NULL );
|
||||
|
||||
int ec;
|
||||
cv_status rc = no_timeout;
|
||||
__TBB_ASSERT( lock.owns, NULL );
|
||||
lock.owns = false;
|
||||
if( ( ec=pthread_cond_timedwait( &my_cv, lock.mutex()->native_handle(), &req ) ) ) {
|
||||
if( ec==ETIMEDOUT )
|
||||
rc = timeout;
|
||||
else {
|
||||
__TBB_ASSERT( lock.try_lock()==false, NULL );
|
||||
lock.owns = true;
|
||||
throw_exception_v4( tbb::internal::eid_condvar_wait_failed );
|
||||
}
|
||||
}
|
||||
lock.owns = true;
|
||||
return rc;
|
||||
}
|
||||
#endif /* !(_WIN32||_WIN64) */
|
||||
|
||||
} // namespace interface5
|
||||
|
||||
__TBB_DEFINE_PROFILING_SET_NAME(interface5::condition_variable)
|
||||
|
||||
} // namespace tbb
|
||||
|
||||
#if TBB_IMPLEMENT_CPP0X
|
||||
|
||||
namespace std {
|
||||
|
||||
using tbb::interface5::defer_lock_t;
|
||||
using tbb::interface5::try_to_lock_t;
|
||||
using tbb::interface5::adopt_lock_t;
|
||||
using tbb::interface5::defer_lock;
|
||||
using tbb::interface5::try_to_lock;
|
||||
using tbb::interface5::adopt_lock;
|
||||
using tbb::interface5::lock_guard;
|
||||
using tbb::interface5::unique_lock;
|
||||
using tbb::interface5::swap; /* this is for void std::swap(unique_lock<M>&,unique_lock<M>&) */
|
||||
using tbb::interface5::condition_variable;
|
||||
using tbb::interface5::cv_status;
|
||||
using tbb::interface5::timeout;
|
||||
using tbb::interface5::no_timeout;
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif /* TBB_IMPLEMENT_CPP0X */
|
||||
|
||||
#endif /* __TBB_condition_variable_H */
|
||||
62
Research/inc/tbb/compat/ppl.h
Normal file
62
Research/inc/tbb/compat/ppl.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright 2005-2015 Intel Corporation. All Rights Reserved.
|
||||
|
||||
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
|
||||
you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation. Threading Building Blocks is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details. You should have received a copy of
|
||||
the GNU General Public License along with Threading Building Blocks; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
As a special exception, you may use this file as part of a free software library without
|
||||
restriction. Specifically, if other files instantiate templates or use macros or inline
|
||||
functions from this file, or you compile this file and link it with other files to produce
|
||||
an executable, this file does not by itself cause the resulting executable to be covered
|
||||
by the GNU General Public License. This exception does not however invalidate any other
|
||||
reasons why the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef __TBB_compat_ppl_H
|
||||
#define __TBB_compat_ppl_H
|
||||
|
||||
#include "../task_group.h"
|
||||
#include "../parallel_invoke.h"
|
||||
#include "../parallel_for_each.h"
|
||||
#include "../parallel_for.h"
|
||||
#include "../tbb_exception.h"
|
||||
#include "../critical_section.h"
|
||||
#include "../reader_writer_lock.h"
|
||||
#include "../combinable.h"
|
||||
|
||||
namespace Concurrency {
|
||||
|
||||
#if __TBB_TASK_GROUP_CONTEXT
|
||||
using tbb::task_handle;
|
||||
using tbb::task_group_status;
|
||||
using tbb::task_group;
|
||||
using tbb::structured_task_group;
|
||||
using tbb::invalid_multiple_scheduling;
|
||||
using tbb::missing_wait;
|
||||
using tbb::make_task;
|
||||
|
||||
using tbb::not_complete;
|
||||
using tbb::complete;
|
||||
using tbb::canceled;
|
||||
|
||||
using tbb::is_current_task_group_canceling;
|
||||
#endif /* __TBB_TASK_GROUP_CONTEXT */
|
||||
|
||||
using tbb::parallel_invoke;
|
||||
using tbb::strict_ppl::parallel_for;
|
||||
using tbb::parallel_for_each;
|
||||
using tbb::critical_section;
|
||||
using tbb::reader_writer_lock;
|
||||
using tbb::combinable;
|
||||
|
||||
using tbb::improper_lock;
|
||||
|
||||
} // namespace Concurrency
|
||||
|
||||
#endif /* __TBB_compat_ppl_H */
|
||||
46
Research/inc/tbb/compat/thread
Normal file
46
Research/inc/tbb/compat/thread
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2005-2015 Intel Corporation. All Rights Reserved.
|
||||
|
||||
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
|
||||
you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation. Threading Building Blocks is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details. You should have received a copy of
|
||||
the GNU General Public License along with Threading Building Blocks; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
As a special exception, you may use this file as part of a free software library without
|
||||
restriction. Specifically, if other files instantiate templates or use macros or inline
|
||||
functions from this file, or you compile this file and link it with other files to produce
|
||||
an executable, this file does not by itself cause the resulting executable to be covered
|
||||
by the GNU General Public License. This exception does not however invalidate any other
|
||||
reasons why the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef __TBB_thread_H
|
||||
#define __TBB_thread_H
|
||||
|
||||
#include "../tbb_thread.h"
|
||||
|
||||
#if TBB_IMPLEMENT_CPP0X
|
||||
|
||||
namespace std {
|
||||
|
||||
typedef tbb::tbb_thread thread;
|
||||
|
||||
namespace this_thread {
|
||||
using tbb::this_tbb_thread::get_id;
|
||||
using tbb::this_tbb_thread::yield;
|
||||
|
||||
inline void sleep_for(const tbb::tick_count::interval_t& rel_time) {
|
||||
tbb::internal::thread_sleep_v3( rel_time );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* TBB_IMPLEMENT_CPP0X */
|
||||
|
||||
#endif /* __TBB_thread_H */
|
||||
488
Research/inc/tbb/compat/tuple
Normal file
488
Research/inc/tbb/compat/tuple
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
Copyright 2005-2015 Intel Corporation. All Rights Reserved.
|
||||
|
||||
This file is part of Threading Building Blocks. Threading Building Blocks is free software;
|
||||
you can redistribute it and/or modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation. Threading Building Blocks is
|
||||
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details. You should have received a copy of
|
||||
the GNU General Public License along with Threading Building Blocks; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
As a special exception, you may use this file as part of a free software library without
|
||||
restriction. Specifically, if other files instantiate templates or use macros or inline
|
||||
functions from this file, or you compile this file and link it with other files to produce
|
||||
an executable, this file does not by itself cause the resulting executable to be covered
|
||||
by the GNU General Public License. This exception does not however invalidate any other
|
||||
reasons why the executable file might be covered by the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef __TBB_tuple_H
|
||||
#define __TBB_tuple_H
|
||||
|
||||
#include <utility>
|
||||
#include "../tbb_stddef.h"
|
||||
|
||||
// build preprocessor variables for varying number of arguments
|
||||
// Need the leading comma so the empty __TBB_T_PACK will not cause a syntax error.
|
||||
#if __TBB_VARIADIC_MAX <= 5
|
||||
#define __TBB_T_PACK
|
||||
#define __TBB_U_PACK
|
||||
#define __TBB_TYPENAME_T_PACK
|
||||
#define __TBB_TYPENAME_U_PACK
|
||||
#define __TBB_NULL_TYPE_PACK
|
||||
#define __TBB_REF_T_PARAM_PACK
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK
|
||||
#define __TBB_T_PARAM_LIST_PACK
|
||||
#define __TBB_CONST_NULL_REF_PACK
|
||||
//
|
||||
#elif __TBB_VARIADIC_MAX == 6
|
||||
#define __TBB_T_PACK ,__T5
|
||||
#define __TBB_U_PACK ,__U5
|
||||
#define __TBB_TYPENAME_T_PACK , typename __T5
|
||||
#define __TBB_TYPENAME_U_PACK , typename __U5
|
||||
#define __TBB_NULL_TYPE_PACK , null_type
|
||||
#define __TBB_REF_T_PARAM_PACK ,__T5& t5
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5
|
||||
#define __TBB_T_PARAM_LIST_PACK ,t5
|
||||
#define __TBB_CONST_NULL_REF_PACK , const null_type&
|
||||
//
|
||||
#elif __TBB_VARIADIC_MAX == 7
|
||||
#define __TBB_T_PACK ,__T5, __T6
|
||||
#define __TBB_U_PACK ,__U5, __U6
|
||||
#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6
|
||||
#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6
|
||||
#define __TBB_NULL_TYPE_PACK , null_type, null_type
|
||||
#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6
|
||||
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6
|
||||
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&
|
||||
//
|
||||
#elif __TBB_VARIADIC_MAX == 8
|
||||
#define __TBB_T_PACK ,__T5, __T6, __T7
|
||||
#define __TBB_U_PACK ,__U5, __U6, __U7
|
||||
#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T7
|
||||
#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U7
|
||||
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type
|
||||
#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7
|
||||
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7
|
||||
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&
|
||||
//
|
||||
#elif __TBB_VARIADIC_MAX == 9
|
||||
#define __TBB_T_PACK ,__T5, __T6, __T7, __T8
|
||||
#define __TBB_U_PACK ,__U5, __U6, __U7, __U8
|
||||
#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8
|
||||
#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8
|
||||
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type
|
||||
#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8
|
||||
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8
|
||||
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&
|
||||
//
|
||||
#elif __TBB_VARIADIC_MAX >= 10
|
||||
#define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9
|
||||
#define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9
|
||||
#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8, typename __T9
|
||||
#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8, typename __U9
|
||||
#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type
|
||||
#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T9& t9
|
||||
#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8, const __T9& t9
|
||||
#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9
|
||||
#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&, const null_type&
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace tbb {
|
||||
namespace interface5 {
|
||||
|
||||
namespace internal {
|
||||
struct null_type { };
|
||||
}
|
||||
using internal::null_type;
|
||||
|
||||
// tuple forward declaration
|
||||
template <typename __T0=null_type, typename __T1=null_type, typename __T2=null_type,
|
||||
typename __T3=null_type, typename __T4=null_type
|
||||
#if __TBB_VARIADIC_MAX >= 6
|
||||
, typename __T5=null_type
|
||||
#if __TBB_VARIADIC_MAX >= 7
|
||||
, typename __T6=null_type
|
||||
#if __TBB_VARIADIC_MAX >= 8
|
||||
, typename __T7=null_type
|
||||
#if __TBB_VARIADIC_MAX >= 9
|
||||
, typename __T8=null_type
|
||||
#if __TBB_VARIADIC_MAX >= 10
|
||||
, typename __T9=null_type
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
>
|
||||
class tuple;
|
||||
|
||||
namespace internal {
|
||||
|
||||
// const null_type temp
|
||||
inline const null_type cnull() { return null_type(); }
|
||||
|
||||
// cons forward declaration
|
||||
template <typename __HT, typename __TT> struct cons;
|
||||
|
||||
// type of a component of the cons
|
||||
template<int __N, typename __T>
|
||||
struct component {
|
||||
typedef typename __T::tail_type next;
|
||||
typedef typename component<__N-1,next>::type type;
|
||||
};
|
||||
|
||||
template<typename __T>
|
||||
struct component<0,__T> {
|
||||
typedef typename __T::head_type type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct component<0,null_type> {
|
||||
typedef null_type type;
|
||||
};
|
||||
|
||||
// const version of component
|
||||
|
||||
template<int __N, typename __T>
|
||||
struct component<__N, const __T>
|
||||
{
|
||||
typedef typename __T::tail_type next;
|
||||
typedef const typename component<__N-1,next>::type type;
|
||||
};
|
||||
|
||||
template<typename __T>
|
||||
struct component<0, const __T>
|
||||
{
|
||||
typedef const typename __T::head_type type;
|
||||
};
|
||||
|
||||
|
||||
// helper class for getting components of cons
|
||||
template< int __N>
|
||||
struct get_helper {
|
||||
template<typename __HT, typename __TT>
|
||||
inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) {
|
||||
return get_helper<__N-1>::get(ti.tail);
|
||||
}
|
||||
template<typename __HT, typename __TT>
|
||||
inline static typename component<__N, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) {
|
||||
return get_helper<__N-1>::get(ti.tail);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct get_helper<0> {
|
||||
template<typename __HT, typename __TT>
|
||||
inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) {
|
||||
return ti.head;
|
||||
}
|
||||
template<typename __HT, typename __TT>
|
||||
inline static typename component<0, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) {
|
||||
return ti.head;
|
||||
}
|
||||
};
|
||||
|
||||
// traits adaptor
|
||||
template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK>
|
||||
struct tuple_traits {
|
||||
typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_T_PACK , null_type>::U > U;
|
||||
};
|
||||
|
||||
template <typename __T0>
|
||||
struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > {
|
||||
typedef cons<__T0, null_type> U;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct tuple_traits<null_type, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > {
|
||||
typedef null_type U;
|
||||
};
|
||||
|
||||
|
||||
// core cons defs
|
||||
template <typename __HT, typename __TT>
|
||||
struct cons{
|
||||
|
||||
typedef __HT head_type;
|
||||
typedef __TT tail_type;
|
||||
|
||||
head_type head;
|
||||
tail_type tail;
|
||||
|
||||
static const int length = 1 + tail_type::length;
|
||||
|
||||
// default constructors
|
||||
explicit cons() : head(), tail() { }
|
||||
|
||||
// non-default constructors
|
||||
cons(head_type& h, const tail_type& t) : head(h), tail(t) { }
|
||||
|
||||
template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
|
||||
cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, const __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) :
|
||||
head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { }
|
||||
|
||||
template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
|
||||
cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM_PACK) :
|
||||
head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { }
|
||||
|
||||
template <typename __HT1, typename __TT1>
|
||||
cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tail) { }
|
||||
|
||||
cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; }
|
||||
|
||||
friend bool operator==(const cons& me, const cons& other) {
|
||||
return me.head == other.head && me.tail == other.tail;
|
||||
}
|
||||
friend bool operator<(const cons& me, const cons& other) {
|
||||
return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
|
||||
}
|
||||
friend bool operator>(const cons& me, const cons& other) { return other<me; }
|
||||
friend bool operator!=(const cons& me, const cons& other) { return !(me==other); }
|
||||
friend bool operator>=(const cons& me, const cons& other) { return !(me<other); }
|
||||
friend bool operator<=(const cons& me, const cons& other) { return !(me>other); }
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) {
|
||||
return me.head == other.head && me.tail == other.tail;
|
||||
}
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) {
|
||||
return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
|
||||
}
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return other<me; }
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me==other); }
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me<other); }
|
||||
|
||||
template<typename __HT1, typename __TT1>
|
||||
friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me>other); }
|
||||
|
||||
|
||||
}; // cons
|
||||
|
||||
|
||||
template <typename __HT>
|
||||
struct cons<__HT,null_type> {
|
||||
|
||||
typedef __HT head_type;
|
||||
typedef null_type tail_type;
|
||||
|
||||
head_type head;
|
||||
|
||||
static const int length = 1;
|
||||
|
||||
// default constructor
|
||||
cons() : head() { /*std::cout << "default constructor 1\n";*/ }
|
||||
|
||||
cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ }
|
||||
|
||||
// non-default constructor
|
||||
template<typename __T1>
|
||||
cons(__T1& t1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/}
|
||||
|
||||
cons(head_type& h, const null_type& = null_type() ) : head(h) { }
|
||||
cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { }
|
||||
|
||||
// converting constructor
|
||||
template<typename __HT1>
|
||||
cons(__HT1 h1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { }
|
||||
|
||||
// copy constructor
|
||||
template<typename __HT1>
|
||||
cons( const cons<__HT1, null_type>& other) : head(other.head) { }
|
||||
|
||||
// assignment operator
|
||||
cons& operator=(const cons& other) { head = other.head; return *this; }
|
||||
|
||||
friend bool operator==(const cons& me, const cons& other) { return me.head == other.head; }
|
||||
friend bool operator<(const cons& me, const cons& other) { return me.head < other.head; }
|
||||
friend bool operator>(const cons& me, const cons& other) { return other<me; }
|
||||
friend bool operator!=(const cons& me, const cons& other) {return !(me==other); }
|
||||
friend bool operator<=(const cons& me, const cons& other) {return !(me>other); }
|
||||
friend bool operator>=(const cons& me, const cons& other) {return !(me<other); }
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) {
|
||||
return me.head == other.head;
|
||||
}
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) {
|
||||
return me.head < other.head;
|
||||
}
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return other<me; }
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me==other); }
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me>other); }
|
||||
|
||||
template<typename __HT1>
|
||||
friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me<other); }
|
||||
|
||||
}; // cons
|
||||
|
||||
template <>
|
||||
struct cons<null_type,null_type> { typedef null_type tail_type; static const int length = 0; };
|
||||
|
||||
// wrapper for default constructor
|
||||
template<typename __T>
|
||||
inline const __T wrap_dcons(__T*) { return __T(); }
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// tuple definition
|
||||
template<typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
|
||||
class tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __TBB_T_PACK >::U {
|
||||
// friends
|
||||
template <typename __T> friend class tuple_size;
|
||||
template<int __N, typename __T> friend struct tuple_element;
|
||||
|
||||
// stl components
|
||||
typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef const value_type *const_pointer;
|
||||
typedef value_type &reference;
|
||||
typedef const value_type &const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB_T_PACK >::U my_cons;
|
||||
|
||||
public:
|
||||
tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL)
|
||||
,const __T1& t1=internal::wrap_dcons((__T1*)NULL)
|
||||
,const __T2& t2=internal::wrap_dcons((__T2*)NULL)
|
||||
,const __T3& t3=internal::wrap_dcons((__T3*)NULL)
|
||||
,const __T4& t4=internal::wrap_dcons((__T4*)NULL)
|
||||
#if __TBB_VARIADIC_MAX >= 6
|
||||
,const __T5& t5=internal::wrap_dcons((__T5*)NULL)
|
||||
#if __TBB_VARIADIC_MAX >= 7
|
||||
,const __T6& t6=internal::wrap_dcons((__T6*)NULL)
|
||||
#if __TBB_VARIADIC_MAX >= 8
|
||||
,const __T7& t7=internal::wrap_dcons((__T7*)NULL)
|
||||
#if __TBB_VARIADIC_MAX >= 9
|
||||
,const __T8& t8=internal::wrap_dcons((__T8*)NULL)
|
||||
#if __TBB_VARIADIC_MAX >= 10
|
||||
,const __T9& t9=internal::wrap_dcons((__T9*)NULL)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
) :
|
||||
my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { }
|
||||
|
||||
template<int __N>
|
||||
struct internal_tuple_element {
|
||||
typedef typename internal::component<__N,my_cons>::type type;
|
||||
};
|
||||
|
||||
template<int __N>
|
||||
typename internal_tuple_element<__N>::type& get() { return internal::get_helper<__N>::get(*this); }
|
||||
|
||||
template<int __N>
|
||||
typename internal_tuple_element<__N>::type const& get() const { return internal::get_helper<__N>::get(*this); }
|
||||
|
||||
template<typename __U1, typename __U2>
|
||||
tuple& operator=(const internal::cons<__U1,__U2>& other) {
|
||||
my_cons::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename __U1, typename __U2>
|
||||
tuple& operator=(const std::pair<__U1,__U2>& other) {
|
||||
// __TBB_ASSERT(tuple_size<value_type>::value == 2, "Invalid size for pair to tuple assignment");
|
||||
this->head = other.first;
|
||||
this->tail.head = other.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend bool operator==(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)==(other);}
|
||||
friend bool operator<(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)<(other);}
|
||||
friend bool operator>(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)>(other);}
|
||||
friend bool operator!=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)!=(other);}
|
||||
friend bool operator>=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)>=(other);}
|
||||
friend bool operator<=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)<=(other);}
|
||||
|
||||
}; // tuple
|
||||
|
||||
// empty tuple
|
||||
template<>
|
||||
class tuple<null_type, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > : public null_type {
|
||||
};
|
||||
|
||||
// helper classes
|
||||
|
||||
template < typename __T>
|
||||
class tuple_size {
|
||||
public:
|
||||
static const size_t value = 1 + tuple_size<typename __T::tail_type>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
class tuple_size<tuple<> > {
|
||||
public:
|
||||
static const size_t value = 0;
|
||||
};
|
||||
|
||||
template <>
|
||||
class tuple_size<null_type> {
|
||||
public:
|
||||
static const size_t value = 0;
|
||||
};
|
||||
|
||||
template<int __N, typename __T>
|
||||
struct tuple_element {
|
||||
typedef typename internal::component<__N, typename __T::my_cons>::type type;
|
||||
};
|
||||
|
||||
template<int __N, typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
|
||||
inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type&
|
||||
get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); }
|
||||
|
||||
template<int __N, typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
|
||||
inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type const&
|
||||
get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); }
|
||||
|
||||
} // interface5
|
||||
} // tbb
|
||||
|
||||
#if !__TBB_CPP11_TUPLE_PRESENT
|
||||
namespace tbb {
|
||||
namespace flow {
|
||||
using tbb::interface5::tuple;
|
||||
using tbb::interface5::tuple_size;
|
||||
using tbb::interface5::tuple_element;
|
||||
using tbb::interface5::get;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef __TBB_T_PACK
|
||||
#undef __TBB_U_PACK
|
||||
#undef __TBB_TYPENAME_T_PACK
|
||||
#undef __TBB_TYPENAME_U_PACK
|
||||
#undef __TBB_NULL_TYPE_PACK
|
||||
#undef __TBB_REF_T_PARAM_PACK
|
||||
#undef __TBB_CONST_REF_T_PARAM_PACK
|
||||
#undef __TBB_T_PARAM_LIST_PACK
|
||||
#undef __TBB_CONST_NULL_REF_PACK
|
||||
|
||||
#endif /* __TBB_tuple_H */
|
||||
Reference in New Issue
Block a user