| 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_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 | |
|