blocked_range.h   blocked_range.h 
skipping to change at line 102 skipping to change at line 102
my_end(r.my_end), my_end(r.my_end),
my_begin(do_split(r, split())), my_begin(do_split(r, split())),
my_grainsize(r.my_grainsize) my_grainsize(r.my_grainsize)
{ {
// only comparison 'less than' is required from values of blocked_r ange objects // only comparison 'less than' is required from values of blocked_r ange objects
__TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "bl ocked_range has been split incorrectly" ); __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "bl ocked_range has been split incorrectly" );
} }
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
//! Static field to support proportional split //! Static field to support proportional split
static const bool is_divisible_in_proportion = true; static const bool is_splittable_in_proportion = true;
//! Split range. //! Split range.
/** The new Range *this has the second part split according to specifie d proportion, the old range r has the first part. /** The new Range *this has the second part split according to specifie d proportion, the old range r has the first part.
Unspecified if end()<begin() or !is_divisible(). */ Unspecified if end()<begin() or !is_divisible(). */
blocked_range( blocked_range& r, proportional_split& proportion ) : blocked_range( blocked_range& r, proportional_split& proportion ) :
my_end(r.my_end), my_end(r.my_end),
my_begin(do_split(r, proportion)), my_begin(do_split(r, proportion)),
my_grainsize(r.my_grainsize) my_grainsize(r.my_grainsize)
{ {
// only comparison 'less than' is required from values of blocked_r ange objects // only comparison 'less than' is required from values of blocked_r ange objects
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 blocked_range2d.h   blocked_range2d.h 
skipping to change at line 79 skipping to change at line 79
blocked_range2d( blocked_range2d& r, split ) : blocked_range2d( blocked_range2d& r, split ) :
my_rows(r.my_rows), my_rows(r.my_rows),
my_cols(r.my_cols) my_cols(r.my_cols)
{ {
split split_obj; split split_obj;
do_split(r, split_obj); do_split(r, split_obj);
} }
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
//! Static field to support proportional split //! Static field to support proportional split
static const bool is_divisible_in_proportion = true; static const bool is_splittable_in_proportion = true;
blocked_range2d( blocked_range2d& r, proportional_split& proportion ) : blocked_range2d( blocked_range2d& r, proportional_split& proportion ) :
my_rows(r.my_rows), my_rows(r.my_rows),
my_cols(r.my_cols) my_cols(r.my_cols)
{ {
do_split(r, proportion); do_split(r, proportion);
} }
#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
template <typename Split> template <typename Split>
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 blocked_range3d.h   blocked_range3d.h 
skipping to change at line 86 skipping to change at line 86
my_pages(r.my_pages), my_pages(r.my_pages),
my_rows(r.my_rows), my_rows(r.my_rows),
my_cols(r.my_cols) my_cols(r.my_cols)
{ {
split split_obj; split split_obj;
do_split(r, split_obj); do_split(r, split_obj);
} }
#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES #if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
//! Static field to support proportional split //! Static field to support proportional split
static const bool is_divisible_in_proportion = true; static const bool is_splittable_in_proportion = true;
blocked_range3d( blocked_range3d& r, proportional_split& proportion ) : blocked_range3d( blocked_range3d& r, proportional_split& proportion ) :
my_pages(r.my_pages), my_pages(r.my_pages),
my_rows(r.my_rows), my_rows(r.my_rows),
my_cols(r.my_cols) my_cols(r.my_cols)
{ {
do_split(r, proportion); do_split(r, proportion);
} }
#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */ #endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 partitioner.h   partitioner.h 
skipping to change at line 275 skipping to change at line 275
} while( !range_pool.empty() && !start.is_cancelled() ); } while( !range_pool.empty() && !start.is_cancelled() );
} }
} }
}; };
//! Provides default methods for auto (adaptive) partition objects. //! Provides default methods for auto (adaptive) partition objects.
template <typename Partition> template <typename Partition>
struct adaptive_partition_type_base : partition_type_base<Partition> { struct adaptive_partition_type_base : partition_type_base<Partition> {
size_t my_divisor; size_t my_divisor;
depth_t my_max_depth; depth_t my_max_depth;
static const unsigned factor = 1;
adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) { adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) {
my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4; my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4 * Partition::factor;
__TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partiti oner_divisor() is not valid"); __TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partiti oner_divisor() is not valid");
} }
adaptive_partition_type_base(adaptive_partition_type_base &src, split) { adaptive_partition_type_base(adaptive_partition_type_base &src, split) {
my_max_depth = src.my_max_depth; my_max_depth = src.my_max_depth;
#if TBB_USE_ASSERT #if TBB_USE_ASSERT
size_t old_divisor = src.my_divisor; size_t old_divisor = src.my_divisor;
#endif #endif
#if __TBB_INITIAL_TASK_IMBALANCE #if __TBB_INITIAL_TASK_IMBALANCE
if( src.my_divisor <= 1 ) my_divisor = 0; if( src.my_divisor <= 1 ) my_divisor = 0;
skipping to change at line 302 skipping to change at line 303
#endif #endif
// For affinity_partitioner, my_divisor indicates the number of aff inity array indices the task reserves. // For affinity_partitioner, my_divisor indicates the number of aff inity array indices the task reserves.
// A task which has only one index must produce the right split wit hout reserved index in order to avoid // A task which has only one index must produce the right split wit hout reserved index in order to avoid
// it to be overwritten in note_affinity() of the created (right) t ask. // it to be overwritten in note_affinity() of the created (right) t ask.
// I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order) // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order)
__TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) || __TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) ||
(old_divisor > 1 && my_divisor != 0), NULL); (old_divisor > 1 && my_divisor != 0), NULL);
} }
adaptive_partition_type_base(adaptive_partition_type_base &src, const p roportional_split& split_obj) { adaptive_partition_type_base(adaptive_partition_type_base &src, const p roportional_split& split_obj) {
my_max_depth = src.my_max_depth; my_max_depth = src.my_max_depth;
#if __TBB_ENABLE_RANGE_FEEDBACK
my_divisor = size_t(float(src.my_divisor) * float(split_obj.right() ) my_divisor = size_t(float(src.my_divisor) * float(split_obj.right() )
/ float(split_obj.left() + split_obj.right())); / float(split_obj.left() + split_obj.right()));
#else
my_divisor = split_obj.right() * Partition::factor;
#endif
src.my_divisor -= my_divisor; src.my_divisor -= my_divisor;
} }
bool check_being_stolen( task &t) { // part of old should_execute_range () bool check_being_stolen( task &t) { // part of old should_execute_range ()
if( !my_divisor ) { // if not from the top P tasks of binary tree if( !my_divisor ) { // if not from the top P tasks of binary tree
my_divisor = 1; // TODO: replace by on-stack flag (partition_st ate's member)? my_divisor = 1; // TODO: replace by on-stack flag (partition_st ate's member)?
if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // r uns concurrently with the left task if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // r uns concurrently with the left task
#if TBB_USE_EXCEPTIONS #if TBB_USE_EXCEPTIONS
// RTTI is available, check whether the cast is valid // RTTI is available, check whether the cast is valid
__TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0); __TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0);
// correctness of the cast relies on avoiding the root task for which: // correctness of the cast relies on avoiding the root task for which:
skipping to change at line 332 skipping to change at line 337
} }
return false; return false;
} }
void align_depth(depth_t base) { void align_depth(depth_t base) {
__TBB_ASSERT(base <= my_max_depth, 0); __TBB_ASSERT(base <= my_max_depth, 0);
my_max_depth -= base; my_max_depth -= base;
} }
depth_t max_depth() { return my_max_depth; } depth_t max_depth() { return my_max_depth; }
}; };
//! Helper that enables one or the other code branches (see example in is_r ange_divisible_in_proportion) //! Helper that enables one or the other code branches (see example in is_s plittable_in_proportion)
template<bool C, typename T = void> struct enable_if { typedef T type; }; template<bool C, typename T = void> struct enable_if { typedef T type; };
template<typename T> struct enable_if<false, T> { }; template<typename T> struct enable_if<false, T> { };
//! Class determines whether template parameter has static boolean //! Class determines whether template parameter has static boolean constant
//! constant 'is_divisible_in_proportion' initialized with value of //! 'is_splittable_in_proportion' initialized with value of 'true' or not.
//! 'true' or not. /** If template parameter has such field that has been initialized with non
/** If template parameter has such field that has been initialized -zero
* with non-zero value then class field will be set to 'true', * value then class field will be set to 'true', otherwise - 'false'
* otherwise - 'false'
*/ */
template <typename Range> template <typename Range>
class is_range_divisible_in_proportion { class is_splittable_in_proportion {
private: private:
typedef char yes[1]; typedef char yes[1];
typedef char no [2]; typedef char no [2];
template <typename range_type> static yes& decide(typename enable_if<ra nge_type::is_divisible_in_proportion>::type *); template <typename range_type> static yes& decide(typename enable_if<ra nge_type::is_splittable_in_proportion>::type *);
template <typename range_type> static no& decide(...); template <typename range_type> static no& decide(...);
public: public:
// equals to 'true' if and only if static const variable 'is_divisible_ in_proportion' of template parameter // equals to 'true' if and only if static const variable 'is_splittable _in_proportion' of template parameter
// initialized with the value of 'true' // initialized with the value of 'true'
static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes)); static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes));
}; };
//! Provides default methods for affinity (adaptive) partition objects. //! Provides default methods for affinity (adaptive) partition objects.
class affinity_partition_type : public adaptive_partition_type_base<affinit y_partition_type> { class affinity_partition_type : public adaptive_partition_type_base<affinit y_partition_type> {
static const unsigned factor_power = 4; static const unsigned factor_power = 4;
static const unsigned factor = 1<<factor_power; // number of slots in affinity array per task
enum { enum {
start = 0, start = 0,
run, run,
pass pass
} my_delay; } my_delay;
#ifdef __TBB_USE_MACHINE_TIME_STAMPS #ifdef __TBB_USE_MACHINE_TIME_STAMPS
machine_tsc_t my_dst_tsc; machine_tsc_t my_dst_tsc;
#endif #endif
size_t my_begin; size_t my_begin;
tbb::internal::affinity_id* my_array; tbb::internal::affinity_id* my_array;
public: public:
static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task
typedef proportional_split split_type; typedef proportional_split split_type;
affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& a p ) affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& a p )
: adaptive_partition_type_base<affinity_partition_type>(), : adaptive_partition_type_base<affinity_partition_type>(), my_delay
my_delay(start) (start)
#ifdef __TBB_USE_MACHINE_TIME_STAMPS #ifdef __TBB_USE_MACHINE_TIME_STAMPS
, my_dst_tsc(0) , my_dst_tsc(0)
#endif #endif
{ {
__TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" );
my_divisor *= factor;
ap.resize(factor); ap.resize(factor);
my_array = ap.my_array; my_array = ap.my_array;
my_begin = 0; my_begin = 0;
my_max_depth = factor_power + 1; // the first factor_power ranges w ill be spawned, and >=1 ranges should be left my_max_depth = factor_power + 1; // the first factor_power ranges w ill be spawned, and >=1 ranges should be left
__TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 ); __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 );
} }
affinity_partition_type(affinity_partition_type& p, split) affinity_partition_type(affinity_partition_type& p, split)
: adaptive_partition_type_base<affinity_partition_type>(p, split()) , : adaptive_partition_type_base<affinity_partition_type>(p, split()) ,
my_delay(pass), my_delay(pass),
#ifdef __TBB_USE_MACHINE_TIME_STAMPS #ifdef __TBB_USE_MACHINE_TIME_STAMPS
skipping to change at line 410 skipping to change at line 411
affinity_partition_type(affinity_partition_type& p, const proportional_ split& split_obj) affinity_partition_type(affinity_partition_type& p, const proportional_ split& split_obj)
: adaptive_partition_type_base<affinity_partition_type>(p, split_ob j), : adaptive_partition_type_base<affinity_partition_type>(p, split_ob j),
my_delay(start), my_delay(start),
#ifdef __TBB_USE_MACHINE_TIME_STAMPS #ifdef __TBB_USE_MACHINE_TIME_STAMPS
my_dst_tsc(0), my_dst_tsc(0),
#endif #endif
my_array(p.my_array) { my_array(p.my_array) {
size_t total_divisor = my_divisor + p.my_divisor; size_t total_divisor = my_divisor + p.my_divisor;
__TBB_ASSERT(total_divisor % factor == 0, NULL); __TBB_ASSERT(total_divisor % factor == 0, NULL);
my_divisor = (my_divisor + factor/2) & (0u - factor); my_divisor = (my_divisor + factor/2) & (0u - factor);
#if __TBB_ENABLE_RANGE_FEEDBACK
if (!my_divisor) if (!my_divisor)
my_divisor = factor; my_divisor = factor;
else if (my_divisor == total_divisor) else if (my_divisor == total_divisor)
my_divisor = total_divisor - factor; my_divisor = total_divisor - factor;
#endif
p.my_divisor = total_divisor - my_divisor; p.my_divisor = total_divisor - my_divisor;
__TBB_ASSERT(my_divisor && p.my_divisor, NULL); __TBB_ASSERT(my_divisor && p.my_divisor, NULL);
my_begin = p.my_begin + p.my_divisor; my_begin = p.my_begin + p.my_divisor;
} }
void set_affinity( task &t ) { void set_affinity( task &t ) {
if( my_divisor ) { if( my_divisor ) {
if( !my_array[my_begin] ) { if( !my_array[my_begin] )
// TODO: consider code reuse for static_paritioner // TODO: consider code reuse for static_paritioner
my_array[my_begin] = affinity_id(my_begin / factor + 1); t.set_affinity( affinity_id(my_begin / factor + 1) );
} else
t.set_affinity( my_array[my_begin] ); t.set_affinity( my_array[my_begin] );
} }
} }
void note_affinity( task::affinity_id id ) { void note_affinity( task::affinity_id id ) {
if( my_divisor ) if( my_divisor )
my_array[my_begin] = id; my_array[my_begin] = id;
} }
bool check_for_demand( task &t ) { bool check_for_demand( task &t ) {
if( pass == my_delay ) { if( pass == my_delay ) {
if( my_divisor > 1 ) // produce affinitized tasks while they ha ve slot in array if( my_divisor > 1 ) // produce affinitized tasks while they ha ve slot in array
return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more
skipping to change at line 471 skipping to change at line 474
return my_divisor > factor; return my_divisor > factor;
} }
#if _MSC_VER && !defined(__INTEL_COMPILER) #if _MSC_VER && !defined(__INTEL_COMPILER)
// Suppress "conditional expression is constant" warning. // Suppress "conditional expression is constant" warning.
#pragma warning( push ) #pragma warning( push )
#pragma warning( disable: 4127 ) #pragma warning( disable: 4127 )
#endif #endif
template <typename Range> template <typename Range>
split_type get_split() { split_type get_split() {
if (is_range_divisible_in_proportion<Range>::value) { if (is_splittable_in_proportion<Range>::value) {
size_t size = my_divisor / factor; size_t size = my_divisor / factor;
#if __TBB_NONUNIFORM_TASK_CREATION #if __TBB_NONUNIFORM_TASK_CREATION
size_t right = (size + 2) / 3; size_t right = (size + 2) / 3;
#else #else
size_t right = size / 2; size_t right = size / 2;
#endif #endif
size_t left = size - right; size_t left = size - right;
return split_type(left, right); return split_type(left, right);
} else { } else {
return split_type(1, 1); return split_type(1, 1);
 End of changes. 19 change blocks. 
21 lines changed or deleted 26 lines changed or added


 tbb_config.h   tbb_config.h 
skipping to change at line 450 skipping to change at line 450
#else #else
/** Default partitioner for parallel loop templates since TBB 2.2 */ /** Default partitioner for parallel loop templates since TBB 2.2 */
#define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner #define __TBB_DEFAULT_PARTITIONER tbb::auto_partitioner
#endif /* TBB_DEPRECATED */ #endif /* TBB_DEPRECATED */
#endif /* !defined(__TBB_DEFAULT_PARTITIONER */ #endif /* !defined(__TBB_DEFAULT_PARTITIONER */
#ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES #ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
#define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1 #define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1
#endif #endif
#ifndef __TBB_ENABLE_RANGE_FEEDBACK
#define __TBB_ENABLE_RANGE_FEEDBACK 0
#endif
#ifdef _VARIADIC_MAX #ifdef _VARIADIC_MAX
#define __TBB_VARIADIC_MAX _VARIADIC_MAX #define __TBB_VARIADIC_MAX _VARIADIC_MAX
#else #else
#if _MSC_VER >= 1700 #if _MSC_VER >= 1700
#define __TBB_VARIADIC_MAX 5 /* current VS11 setting, may change. */ #define __TBB_VARIADIC_MAX 5 /* current VS11 setting, may change. */
#else #else
#define __TBB_VARIADIC_MAX 10 #define __TBB_VARIADIC_MAX 10
#endif #endif
#endif #endif
 End of changes. 1 change blocks. 
0 lines changed or deleted 4 lines changed or added


 tbb_stddef.h   tbb_stddef.h 
skipping to change at line 29 skipping to change at line 29
*/ */
#ifndef __TBB_tbb_stddef_H #ifndef __TBB_tbb_stddef_H
#define __TBB_tbb_stddef_H #define __TBB_tbb_stddef_H
// Marketing-driven product version // Marketing-driven product version
#define TBB_VERSION_MAJOR 4 #define TBB_VERSION_MAJOR 4
#define TBB_VERSION_MINOR 3 #define TBB_VERSION_MINOR 3
// Engineering-focused interface version // Engineering-focused interface version
#define TBB_INTERFACE_VERSION 8000 #define TBB_INTERFACE_VERSION 8001
#define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000
// The oldest major interface version still supported // The oldest major interface version still supported
// To be used in SONAME, manifests, etc. // To be used in SONAME, manifests, etc.
#define TBB_COMPATIBLE_INTERFACE_VERSION 2 #define TBB_COMPATIBLE_INTERFACE_VERSION 2
#define __TBB_STRING_AUX(x) #x #define __TBB_STRING_AUX(x) #x
#define __TBB_STRING(x) __TBB_STRING_AUX(x) #define __TBB_STRING(x) __TBB_STRING_AUX(x)
// We do not need defines below for resource processing on windows // We do not need defines below for resource processing on windows
skipping to change at line 210 skipping to change at line 210
using std::size_t; using std::size_t;
using std::ptrdiff_t; using std::ptrdiff_t;
//! The function returns the interface version of the TBB shared library be ing used. //! The function returns the interface version of the TBB shared library be ing used.
/** /**
* The version it returns is determined at runtime, not at compile/link tim e. * The version it returns is determined at runtime, not at compile/link tim e.
* So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time. * So it can be different than the value of TBB_INTERFACE_VERSION obtained at compile time.
*/ */
extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version(); extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version();
//! Dummy type that distinguishes splitting constructor from copy construct
or.
/**
* See description of parallel_for and parallel_reduce for example usages.
* @ingroup algorithms
*/
class split {
};
//! Type enables transmission of splitting proportion from partitioners to
range objects
/**
* In order to make use of such facility Range objects must implement
* splitting constructor with this type passed and initialize static
* constant boolean field 'is_divisible_in_proportion' with the value
* of 'true'
*/
class proportional_split {
public:
proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left
), my_right(_right) { }
proportional_split(split) : my_left(1), my_right(1) { }
size_t left() const { return my_left; }
size_t right() const { return my_right; }
void set_proportion(size_t _left, size_t _right) {
my_left = _left;
my_right = _right;
}
// used when range does not support proportional split
operator split() const { return split(); }
private:
size_t my_left, my_right;
};
/** /**
* @cond INTERNAL * @cond INTERNAL
* @brief Identifiers declared inside namespace internal should never be us ed directly by client code. * @brief Identifiers declared inside namespace internal should never be us ed directly by client code.
*/ */
namespace internal { namespace internal {
//! Compile-time constant that is upper bound on cache line/sector size. //! Compile-time constant that is upper bound on cache line/sector size.
/** It should be used only in situations where having a compile-time upper /** It should be used only in situations where having a compile-time upper
bound is more useful than a run-time exact answer. bound is more useful than a run-time exact answer.
@ingroup memory_allocation */ @ingroup memory_allocation */
skipping to change at line 402 skipping to change at line 368
// i.e. for strictly positive i and j, with j a power of 2, // i.e. for strictly positive i and j, with j a power of 2,
// determines whether i==j<<k for some nonnegative k (so i==j yields true). // determines whether i==j<<k for some nonnegative k (so i==j yields true).
template<typename argument_integer_type, typename divisor_integer_type> template<typename argument_integer_type, typename divisor_integer_type>
inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integ er_type divisor) { inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integ er_type divisor) {
// Divisor is assumed to be a power of two (which is valid for current uses). // Divisor is assumed to be a power of two (which is valid for current uses).
__TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of t wo" ); __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of t wo" );
return 0 == (arg & (arg - divisor)); return 0 == (arg & (arg - divisor));
} }
//! Utility template function to prevent "unused" warnings by various compi lers. //! Utility template function to prevent "unused" warnings by various compi lers.
template<typename T> template<typename T1> void suppress_unused_warning( const T1& ) {}
void suppress_unused_warning( const T& ) {} template<typename T1, typename T2> void suppress_unused_warning( const T1&,
const T2& ) {}
template<typename T1, typename T2, typename T3> void suppress_unused_warnin
g( const T1&, const T2&, const T3& ) {}
// Struct to be used as a version tag for inline functions. // Struct to be used as a version tag for inline functions.
/** Version tag can be necessary to prevent loader on Linux from using the wrong /** Version tag can be necessary to prevent loader on Linux from using the wrong
symbol in debug builds (when inline functions are compiled as out-of-li ne). **/ symbol in debug builds (when inline functions are compiled as out-of-li ne). **/
struct version_tag_v3 {}; struct version_tag_v3 {};
typedef version_tag_v3 version_tag; typedef version_tag_v3 version_tag;
} // internal } // internal
//! Dummy type that distinguishes splitting constructor from copy construct
or.
/**
* See description of parallel_for and parallel_reduce for example usages.
* @ingroup algorithms
*/
class split {
};
//! Type enables transmission of splitting proportion from partitioners to
range objects
/**
* In order to make use of such facility Range objects must implement
* splitting constructor with this type passed and initialize static
* constant boolean field 'is_splittable_in_proportion' with the value
* of 'true'
*/
class proportional_split: internal::no_assign {
public:
proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left
), my_right(_right) { }
size_t left() const { return my_left; }
size_t right() const { return my_right; }
// used when range does not support proportional split
operator split() const { return split(); }
#if __TBB_ENABLE_RANGE_FEEDBACK
void set_proportion(size_t _left, size_t _right) {
my_left = _left;
my_right = _right;
}
#endif
private:
size_t my_left, my_right;
};
} // tbb } // tbb
// Following is a set of classes and functions typically used in compile-ti me "metaprogramming". // Following is a set of classes and functions typically used in compile-ti me "metaprogramming".
// TODO: move all that to a separate header // TODO: move all that to a separate header
#if __TBB_ALLOCATOR_TRAITS_PRESENT #if __TBB_ALLOCATOR_TRAITS_PRESENT
#include <memory> //for allocator_traits #include <memory> //for allocator_traits
#endif #endif
#if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION #if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION
 End of changes. 4 change blocks. 
40 lines changed or deleted 45 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/