+2008-01-09 Paolo Carlini <pcarlini@suse.de>
+
+ * include/parallel/multiway_merge.h: Reformat to 80 columns;
+ adjust some inline specifiers; other minor style fixes.
+ * include/parallel/losertree.h: Likewise.
+ * include/parallel/list_partition.h: Likewise.
+ * include/parallel/multiseq_selection.h: Likewise.
+ * include/parallel/workstealing.h: Likewise.
+ * include/parallel/base.h: Likewise.
+ * include/parallel/par_loop.h: Likewise.
+ * include/parallel/numeric: Likewise.
+ * include/parallel/quicksort.h: Likewise.
+ * include/parallel/algorithmfwd.h: Likewise.
+ * include/parallel/for_each_selectors.h: Likewise.
+ * include/parallel/omp_loop_static.h: Likewise.
+ * include/parallel/random_shuffle.h: Likewise.
+ * include/parallel/balanced_quicksort.h: Likewise.
+ * include/parallel/set_operations.h: Likewise.
+ * include/parallel/tree.h: Likewise.
+ * include/parallel/merge.h: Likewise.
+ * include/parallel/unique_copy.h: Likewise.
+ * include/parallel/settings.h: Likewise.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/numericfwd.h: Likewise.
+ * include/parallel/search.h: Likewise.
+ * include/parallel/partition.h: Likewise.
+ * include/parallel/compatibility.h: Likewise.
+ * include/parallel/partial_sum.h: Likewise.
+ * include/parallel/find.h: Likewise.
+ * include/parallel/algo.h: Likewise.
+ * include/parallel/queue.h: Likewise.
+ * include/parallel/omp_loop.h: Likewise.
+ * include/parallel/sort.h: Likewise.
+ * include/parallel/random_number.h: Likewise.
+
2008-01-09 Benjamin Kosnik <bkoz@redhat.com>
* docs/html/17_intro/api.html: Fix markup for rope.h.
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- for_each_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::for_each_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy;
__gnu_parallel::for_each_selector<RandomAccessIterator>
RandomAccessOutputIterator out, Predicate pred,
random_access_iterator_tag, random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(last - begin)
- > __gnu_parallel::Settings::
- unique_copy_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(last - begin)
+ > __gnu_parallel::Settings::unique_copy_minimal_n))
return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
else
return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end1 - begin1)
- >= __gnu_parallel::Settings::
- set_union_minimal_n
- || static_cast<__gnu_parallel::
- sequence_index_t>(end2 - begin2)
- >= __gnu_parallel::Settings::
- set_union_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ >= __gnu_parallel::Settings::set_union_minimal_n
+ || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ >= __gnu_parallel::Settings::set_union_minimal_n))
return __gnu_parallel::parallel_set_union(begin1, end1,
begin2, end2, result, pred);
else
random_access_iterator_tag,
random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end1 - begin1)
- >= __gnu_parallel::Settings::
- set_union_minimal_n
- || static_cast<__gnu_parallel::
- sequence_index_t>(end2 - begin2)
- >= __gnu_parallel::Settings::
- set_union_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ >= __gnu_parallel::Settings::set_union_minimal_n
+ || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ >= __gnu_parallel::Settings::set_union_minimal_n))
return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2,
end2, result, pred);
else
random_access_iterator_tag,
random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end1 - begin1)
- >= __gnu_parallel::Settings::
- set_symmetric_difference_minimal_n
- || static_cast<__gnu_parallel::
- sequence_index_t>(end2 - begin2)
- >= __gnu_parallel::Settings::
- set_symmetric_difference_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
+ || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n))
return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1,
begin2, end2,
result, pred);
random_access_iterator_tag,
random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end1 - begin1)
- >= __gnu_parallel::Settings::
- set_difference_minimal_n
- || static_cast<__gnu_parallel::
- sequence_index_t>(end2 - begin2)
- >= __gnu_parallel::Settings::
- set_difference_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ >= __gnu_parallel::Settings::set_difference_minimal_n
+ || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ >= __gnu_parallel::Settings::set_difference_minimal_n))
return __gnu_parallel::parallel_set_difference(begin1, end1,
begin2, end2,
result, pred);
typedef typename traits_type::difference_type difference_type;
typedef __gnu_parallel::sequence_index_t sequence_index_t;
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>
- (end - begin)
- >= __gnu_parallel::Settings::
- count_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::count_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
__gnu_parallel::count_selector<RandomAccessIterator, difference_type>
functionality;
typedef typename traits_type::difference_type difference_type;
typedef __gnu_parallel::sequence_index_t sequence_index_t;
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<sequence_index_t>
- (end - begin)
- >= __gnu_parallel::Settings::
- count_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::count_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
difference_type res = 0;
__gnu_parallel::
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- transform_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::transform_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy = true;
typedef __gnu_parallel::iterator_pair<RandomAccessIterator1,
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION((end1 - begin1)
- >= __gnu_parallel::Settings::
- transform_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ (end1 - begin1) >= __gnu_parallel::Settings::transform_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy = true;
typedef __gnu_parallel::iterator_triple<RandomAccessIterator1,
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- replace_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::replace_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy;
__gnu_parallel::
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- generate_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::generate_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
bool dummy;
__gnu_parallel::generate_selector<RandomAccessIterator>
{
if (begin == end)
return;
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- random_shuffle_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::random_shuffle_minimal_n))
__gnu_parallel::parallel_random_shuffle(begin, end, rand);
else
__gnu_parallel::sequential_random_shuffle(begin, end, rand);
partition_switch(RandomAccessIterator begin, RandomAccessIterator end,
Predicate pred, random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- partition_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::partition_minimal_n))
{
typedef typename std::iterator_traits<RandomAccessIterator>::
difference_type difference_type;
if (begin != end)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- sort_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, false);
else
sort(begin, end, comp, __gnu_parallel::sequential_tag());
{
if (begin != end)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- sort_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::sort_minimal_n))
__gnu_parallel::parallel_sort(begin, end, comp, true);
else
stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
{
- if (_GLIBCXX_PARALLEL_CONDITION((static_cast<__gnu_parallel::
- sequence_index_t>(end1 - begin1)
- >= __gnu_parallel::Settings::
- merge_minimal_n
- || static_cast<__gnu_parallel::
- sequence_index_t>(end2 - begin2)
- >= __gnu_parallel::Settings::
- merge_minimal_n)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ (static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
+ >= __gnu_parallel::Settings::merge_minimal_n
+ || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
+ >= __gnu_parallel::Settings::merge_minimal_n)))
return __gnu_parallel::parallel_merge_advance(begin1, end1,
begin2, end2,
result, (end1 - begin1)
nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
RandomAccessIterator end, Comparator comp)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- nth_element_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::nth_element_minimal_n))
__gnu_parallel::parallel_nth_element(begin, nth, end, comp);
else
nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
RandomAccessIterator end, _Compare comp)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- partial_sort_minimal_n))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::partial_sort_minimal_n))
__gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
else
partial_sort(begin, middle, end, comp,
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- max_element_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::max_element_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
RandomAccessIterator res(begin);
__gnu_parallel::identity_selector<RandomAccessIterator>
__gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced)
{
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
- sequence_index_t>(end - begin)
- >= __gnu_parallel::Settings::
- min_element_minimal_n
- && __gnu_parallel::
- is_parallel(parallelism_tag)))
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::min_element_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
{
RandomAccessIterator res(begin);
__gnu_parallel::identity_selector<RandomAccessIterator>
_RAIter3
transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation,
random_access_iterator_tag, random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::parallelism parallelism_tag);
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BiOperation, typename _Tag1,
template<typename _FIter>
_FIter
- max_element(_FIter, _FIter, __gnu_parallel::parallelism parallelism_tag);
+ max_element(_FIter, _FIter, __gnu_parallel::parallelism);
template<typename _FIter, typename _Compare>
_FIter
typedef typename traits_type::value_type value_type;
typedef typename traits_type::difference_type difference_type;
- RandomAccessIterator pivot_pos = median_of_three_iterators(
- begin, begin + (end - begin) / 2, end - 1, comp);
+ RandomAccessIterator pivot_pos =
+ median_of_three_iterators(begin, begin + (end - begin) / 2,
+ end - 1, comp);
#if defined(_GLIBCXX_ASSERTIONS)
// Must be in between somewhere.
#if _GLIBCXX_ASSERTIONS
RandomAccessIterator r;
- for (r = begin; r != pivot_pos; r++)
+ for (r = begin; r != pivot_pos; ++r)
_GLIBCXX_PARALLEL_ASSERT(comp(*r, *pivot_pos));
- for (; r != end; r++)
+ for (; r != end; ++r)
_GLIBCXX_PARALLEL_ASSERT(!comp(*r, *pivot_pos));
#endif
__gnu_parallel::unary_negate<__gnu_parallel::binder1st
<Comparator, value_type, value_type, bool>, value_type>
pred(__gnu_parallel::binder1st
- <Comparator, value_type, value_type, bool>(
- comp, *pivot_pos));
+ <Comparator, value_type, value_type, bool>(comp,
+ *pivot_pos));
// Find other end of pivot-equal range.
- split_pos2 = __gnu_sequential::partition(
- split_pos1 + 1, end, pred);
+ split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
+ end, pred);
}
else
// Only skip the pivot.
{
// Left side larger.
if (begin != split_pos1)
- tl.leftover_parts.push_front(
- std::make_pair(begin, split_pos1));
+ tl.leftover_parts.push_front(std::make_pair(begin,
+ split_pos1));
current.first = split_pos2;
//current.second = end; //already set anyway
if (omp_get_wtime() >= (search_start + 1.0))
{
sleep(1);
- _GLIBCXX_PARALLEL_ASSERT(
- omp_get_wtime() < (search_start + 1.0));
+ _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime()
+ < (search_start + 1.0));
}
#endif
if (!successfully_stolen)
// 2. The largest range has at most length n
// 3. Each range is larger than half of the range remaining
volatile difference_type elements_leftover = n;
- for (int i = 0; i < num_threads; i++)
+ for (int i = 0; i < num_threads; ++i)
{
tls[i]->elements_leftover = &elements_leftover;
tls[i]->num_threads = num_threads;
#if _GLIBCXX_ASSERTIONS
// All stack must be empty.
Piece dummy;
- for (int i = 1; i < num_threads; i++)
+ for (int i = 1; i < num_threads; ++i)
_GLIBCXX_PARALLEL_ASSERT(!tls[i]->leftover_parts.pop_back(dummy));
#endif
- for (int i = 0; i < num_threads; i++)
+ for (int i = 0; i < num_threads; ++i)
delete tls[i];
delete[] tls;
}
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
template<typename T>
const T&
min(const T& a, const T& b)
- {
- return (a < b) ? a : b;
- };
+ { return (a < b) ? a : b; }
/** @brief Equivalent to std::max. */
template<typename T>
const T&
max(const T& a, const T& b)
- {
- return (a > b) ? a : b;
- };
+ { return (a > b) ? a : b; }
/** @brief Constructs predicate for equality from strict weak
* ordering predicate
* @param comp Comparator.
*/
template<typename RandomAccessIterator, typename Comparator>
-RandomAccessIterator
+ RandomAccessIterator
median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b,
RandomAccessIterator c, Comparator& comp)
{
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
#elif defined(__ECC) //IA-64 version
return _InterlockedExchangeAdd((void*)ptr, addend);
#elif defined(__ICL) || defined(_MSC_VER)
- return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr), addend);
+ return _InterlockedExchangeAdd(reinterpret_cast<volatile long*>(ptr),
+ addend);
#elif defined(__GNUC__)
return __sync_fetch_and_add(ptr, addend);
#elif defined(__SUNPRO_CC) && defined(__sparc)
{
before = *ptr;
after = before + addend;
- } while (atomic_cas_32((volatile unsigned int*)ptr, before, after) != before);
+ } while (atomic_cas_32((volatile unsigned int*)ptr, before,
+ after) != before);
return before;
#else //fallback, slow
#pragma message("slow fetch_and_add_32")
{
before = *ptr;
after = before + addend;
- } while (atomic_cas_64((volatile unsigned long long*)ptr, before, after) != before);
+ } while (atomic_cas_64((volatile unsigned long long*)ptr, before,
+ after) != before);
return before;
#else //fallback, slow
#if defined(__GNUC__) && defined(__i386)
compare_and_swap_32(volatile int32* ptr, int32 comparand, int32 replacement)
{
#if defined(__ICC) //x86 version
- return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand;
+ return _InterlockedCompareExchange((void*)ptr, replacement,
+ comparand) == comparand;
#elif defined(__ECC) //IA-64 version
- return _InterlockedCompareExchange((void*)ptr, replacement, comparand) == comparand;
+ return _InterlockedCompareExchange((void*)ptr, replacement,
+ comparand) == comparand;
#elif defined(__ICL) || defined(_MSC_VER)
- return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), replacement, comparand) == comparand;
+ return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr),
+ replacement, comparand) == comparand;
#elif defined(__GNUC__)
return __sync_bool_compare_and_swap(ptr, comparand, replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- return atomic_cas_32((volatile unsigned int*)ptr, comparand, replacement) == comparand;
+ return atomic_cas_32((volatile unsigned int*)ptr, comparand,
+ replacement) == comparand;
#else
#pragma message("slow compare_and_swap_32")
bool res = false;
#if defined(__ICC) && defined(__x86_64) //x86 version
return cas64<int>(ptr, comparand, replacement) == comparand;
#elif defined(__ECC) //IA-64 version
- return _InterlockedCompareExchange64((void*)ptr, replacement, comparand) == comparand;
+ return _InterlockedCompareExchange64((void*)ptr, replacement,
+ comparand) == comparand;
#elif defined(__ICL) || defined(_MSC_VER)
#ifndef _WIN64
_GLIBCXX_PARALLEL_ASSERT(false); //not available in this case
return 0;
#else
- return _InterlockedCompareExchange64(ptr, replacement, comparand) == comparand;
+ return _InterlockedCompareExchange64(ptr, replacement,
+ comparand) == comparand;
#endif
#elif defined(__GNUC__) && defined(__x86_64)
(defined(__i686) || defined(__pentium4) || defined(__athlon))
return __sync_bool_compare_and_swap(ptr, comparand, replacement);
#elif defined(__SUNPRO_CC) && defined(__sparc)
- return atomic_cas_64((volatile unsigned long long*)ptr, comparand, replacement) == comparand;
+ return atomic_cas_64((volatile unsigned long long*)ptr,
+ comparand, replacement) == comparand;
#else
#if defined(__GNUC__) && defined(__i386)
// XXX -march=native
compare_and_swap(volatile T* ptr, T comparand, T replacement)
{
if (sizeof(T) == sizeof(int32))
- return compare_and_swap_32((volatile int32*) ptr, (int32)comparand, (int32)replacement);
+ return compare_and_swap_32((volatile int32*) ptr,
+ (int32)comparand, (int32)replacement);
else if (sizeof(T) == sizeof(int64))
- return compare_and_swap_64((volatile int64*) ptr, (int64)comparand, (int64)replacement);
+ return compare_and_swap_64((volatile int64*) ptr,
+ (int64)comparand, (int64)replacement);
else
_GLIBCXX_PARALLEL_ASSERT(false);
}
typename RandomAccessIterator2,
typename Pred,
typename Selector>
- std::pair<RandomAccessIterator1, RandomAccessIterator2>
+ inline std::pair<RandomAccessIterator1, RandomAccessIterator2>
find_template(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
RandomAccessIterator2 begin2, Pred pred, Selector selector)
{
{
case Settings::GROWING_BLOCKS:
return find_template(begin1, end1, begin2, pred, selector,
- growing_blocks_tag());
+ growing_blocks_tag());
case Settings::CONSTANT_SIZE_BLOCKS:
return find_template(begin1, end1, begin2, pred, selector,
- constant_size_blocks_tag());
+ constant_size_blocks_tag());
case Settings::EQUAL_SPLIT:
return find_template(begin1, end1, begin2, pred, selector,
- equal_split_tag());
+ equal_split_tag());
default:
_GLIBCXX_PARALLEL_ASSERT(false);
return std::make_pair(begin1, begin2);
omp_destroy_lock(&result_lock);
delete[] borders;
- return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
- begin1 + result, begin2 + result);
+ return
+ std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
+ begin2 + result);
}
#endif
difference_type length = end1 - begin1;
- difference_type sequential_search_size = std::min<difference_type>(
- length, Settings::find_sequential_search_size);
+ difference_type sequential_search_size =
+ std::min<difference_type>(length, Settings::find_sequential_search_size);
// Try it sequentially first.
std::pair<RandomAccessIterator1, RandomAccessIterator2> find_seq_result =
omp_unset_lock(&result_lock);
}
- block_size = std::min<difference_type>(
- block_size * Settings::find_increasing_factor,
- Settings::find_maximum_block_size);
+ block_size =
+ std::min<difference_type>(block_size
+ * Settings::find_increasing_factor,
+ Settings::find_maximum_block_size);
// Get new block, update pointer to next block.
start =
- fetch_and_add<difference_type>(&next_block_start, block_size);
- stop = (length < (start + block_size)) ?
- length : (start + block_size);
+ fetch_and_add<difference_type>(&next_block_start, block_size);
+ stop = ((length < (start + block_size))
+ ? length : (start + block_size));
}
} //parallel
omp_destroy_lock(&result_lock);
// Return iterator on found element.
- return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
- begin1 + result, begin2 + result);
+ return
+ std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
+ begin2 + result);
}
#endif
omp_destroy_lock(&result_lock);
// Return iterator on found element.
- return std::pair<RandomAccessIterator1, RandomAccessIterator2>(
- begin1 + result, begin2 + result);
+ return
+ std::pair<RandomAccessIterator1, RandomAccessIterator2>(begin1 + result,
+ begin2 + result);
}
#endif
} // end namespace
/** @brief std::for_each() selector. */
template<typename It>
- struct for_each_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
- bool
- operator()(Op& o, It i)
- {
- o(*i);
- return true;
- }
- };
+ struct for_each_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object. */
+ template<typename Op>
+ bool
+ operator()(Op& o, It i)
+ {
+ o(*i);
+ return true;
+ }
+ };
/** @brief std::generate() selector. */
template<typename It>
- struct generate_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
- bool
- operator()(Op& o, It i)
- {
- *i = o();
- return true;
- }
- };
+ struct generate_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object. */
+ template<typename Op>
+ bool
+ operator()(Op& o, It i)
+ {
+ *i = o();
+ return true;
+ }
+ };
/** @brief std::fill() selector. */
template<typename It>
- struct fill_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object. */
- template<typename Val>
- bool
- operator()(Val& v, It i)
- {
- *i = v;
- return true;
- }
- };
+ struct fill_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param v Current value.
+ * @param i Iterator referencing object. */
+ template<typename Val>
+ bool
+ operator()(Val& v, It i)
+ {
+ *i = v;
+ return true;
+ }
+ };
/** @brief std::transform() selector, one input sequence variant. */
template<typename It>
- struct transform1_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
- bool
- operator()(Op& o, It i)
- {
- *i.second = o(*i.first);
- return true;
- }
- };
+ struct transform1_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object. */
+ template<typename Op>
+ bool
+ operator()(Op& o, It i)
+ {
+ *i.second = o(*i.first);
+ return true;
+ }
+ };
/** @brief std::transform() selector, two input sequences variant. */
template<typename It>
- struct transform2_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- template<typename Op>
- bool
- operator()(Op& o, It i)
- {
- *i.third = o(*i.first, *i.second);
- return true;
- }
- };
+ struct transform2_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object. */
+ template<typename Op>
+ bool
+ operator()(Op& o, It i)
+ {
+ *i.third = o(*i.first, *i.second);
+ return true;
+ }
+ };
/** @brief std::replace() selector. */
template<typename It, typename T>
- struct replace_selector : public generic_for_each_selector<It>
- {
- /** @brief Value to replace with. */
- const T& new_val;
+ struct replace_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Value to replace with. */
+ const T& new_val;
- /** @brief Constructor
- * @param new_val Value to replace with. */
- explicit replace_selector(const T &new_val) : new_val(new_val) {}
+ /** @brief Constructor
+ * @param new_val Value to replace with. */
+ explicit
+ replace_selector(const T &new_val) : new_val(new_val) {}
- /** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object. */
- bool
- operator()(T& v, It i)
- {
- if (*i == v)
- *i = new_val;
- return true;
- }
- };
+ /** @brief Functor execution.
+ * @param v Current value.
+ * @param i Iterator referencing object. */
+ bool
+ operator()(T& v, It i)
+ {
+ if (*i == v)
+ *i = new_val;
+ return true;
+ }
+ };
/** @brief std::replace() selector. */
template<typename It, typename Op, typename T>
- struct replace_if_selector : public generic_for_each_selector<It>
- {
- /** @brief Value to replace with. */
- const T& new_val;
+ struct replace_if_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Value to replace with. */
+ const T& new_val;
- /** @brief Constructor.
- * @param new_val Value to replace with. */
- explicit replace_if_selector(const T &new_val) : new_val(new_val) { }
+ /** @brief Constructor.
+ * @param new_val Value to replace with. */
+ explicit
+ replace_if_selector(const T &new_val) : new_val(new_val) { }
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object. */
- bool
- operator()(Op& o, It i)
- {
- if (o(*i))
- *i = new_val;
- return true;
- }
- };
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object. */
+ bool
+ operator()(Op& o, It i)
+ {
+ if (o(*i))
+ *i = new_val;
+ return true;
+ }
+ };
/** @brief std::count() selector. */
template<typename It, typename Diff>
- struct count_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param v Current value.
- * @param i Iterator referencing object.
- * @return 1 if count, 0 if does not count. */
- template<typename Val>
- Diff
- operator()(Val& v, It i)
- { return (v == *i) ? 1 : 0; }
- };
+ struct count_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param v Current value.
+ * @param i Iterator referencing object.
+ * @return 1 if count, 0 if does not count. */
+ template<typename Val>
+ Diff
+ operator()(Val& v, It i)
+ { return (v == *i) ? 1 : 0; }
+ };
/** @brief std::count_if () selector. */
template<typename It, typename Diff>
- struct count_if_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator.
- * @param i Iterator referencing object.
- * @return 1 if count, 0 if does not count. */
- template<typename Op>
- Diff
- operator()(Op& o, It i)
- { return (o(*i)) ? 1 : 0; }
- };
+ struct count_if_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator.
+ * @param i Iterator referencing object.
+ * @return 1 if count, 0 if does not count. */
+ template<typename Op>
+ Diff
+ operator()(Op& o, It i)
+ { return (o(*i)) ? 1 : 0; }
+ };
/** @brief std::accumulate() selector. */
template<typename It>
- struct accumulate_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator (unused).
- * @param i Iterator referencing object.
- * @return The current value. */
- template<typename Op>
- typename std::iterator_traits<It>::value_type operator()(Op o, It i)
- { return *i; }
- };
+ struct accumulate_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator (unused).
+ * @param i Iterator referencing object.
+ * @return The current value. */
+ template<typename Op>
+ typename std::iterator_traits<It>::value_type operator()(Op o, It i)
+ { return *i; }
+ };
/** @brief std::inner_product() selector. */
template<typename It, typename It2, typename T>
- struct inner_product_selector : public generic_for_each_selector<It>
- {
- /** @brief Begin iterator of first sequence. */
- It begin1_iterator;
-
- /** @brief Begin iterator of second sequence. */
- It2 begin2_iterator;
-
- /** @brief Constructor.
- * @param b1 Begin iterator of first sequence.
- * @param b2 Begin iterator of second sequence. */
- explicit inner_product_selector(It b1, It2 b2)
- : begin1_iterator(b1), begin2_iterator(b2) { }
-
- /** @brief Functor execution.
- * @param mult Multiplication functor.
- * @param current Iterator referencing object.
- * @return Inner product elemental result. */
- template<typename Op>
- T
- operator()(Op mult, It current)
- {
- typename std::iterator_traits<It>::difference_type position
- = current - begin1_iterator;
- return mult(*current, *(begin2_iterator + position));
- }
- };
+ struct inner_product_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Begin iterator of first sequence. */
+ It begin1_iterator;
+
+ /** @brief Begin iterator of second sequence. */
+ It2 begin2_iterator;
+
+ /** @brief Constructor.
+ * @param b1 Begin iterator of first sequence.
+ * @param b2 Begin iterator of second sequence. */
+ explicit
+ inner_product_selector(It b1, It2 b2)
+ : begin1_iterator(b1), begin2_iterator(b2) { }
+
+ /** @brief Functor execution.
+ * @param mult Multiplication functor.
+ * @param current Iterator referencing object.
+ * @return Inner product elemental result. */
+ template<typename Op>
+ T
+ operator()(Op mult, It current)
+ {
+ typename std::iterator_traits<It>::difference_type position
+ = current - begin1_iterator;
+ return mult(*current, *(begin2_iterator + position));
+ }
+ };
/** @brief Selector that just returns the passed iterator. */
template<typename It>
- struct identity_selector : public generic_for_each_selector<It>
- {
- /** @brief Functor execution.
- * @param o Operator (unused).
- * @param i Iterator referencing object.
- * @return Passed iterator. */
- template<typename Op>
- It
- operator()(Op o, It i)
- { return i; }
- };
+ struct identity_selector : public generic_for_each_selector<It>
+ {
+ /** @brief Functor execution.
+ * @param o Operator (unused).
+ * @param i Iterator referencing object.
+ * @return Passed iterator. */
+ template<typename Op>
+ It
+ operator()(Op o, It i)
+ { return i; }
+ };
/** @brief Selector that returns the difference between two adjacent
* elements.
*/
template<typename It>
- struct adjacent_difference_selector : public generic_for_each_selector<It>
- {
- template<typename Op>
- bool
- operator()(Op& o, It i)
- {
- typename It::first_type go_back_one = i.first;
- --go_back_one;
- *i.second = o(*i.first, *go_back_one);
- return true;
- }
- };
+ struct adjacent_difference_selector : public generic_for_each_selector<It>
+ {
+ template<typename Op>
+ bool
+ operator()(Op& o, It i)
+ {
+ typename It::first_type go_back_one = i.first;
+ --go_back_one;
+ *i.second = o(*i.first, *go_back_one);
+ return true;
+ }
+ };
// XXX move into type_traits?
/** @brief Functor doing nothing
/** @brief Reduction for finding the maximum element, using a comparator. */
template<typename Comp, typename It>
- struct min_element_reduct
- {
- Comp& comp;
+ struct min_element_reduct
+ {
+ Comp& comp;
- explicit min_element_reduct(Comp &c) : comp(c)
- { }
+ explicit
+ min_element_reduct(Comp &c) : comp(c) { }
- It
- operator()(It x, It y)
- {
- if (comp(*x, *y))
- return x;
- else
- return y;
- }
- };
+ It
+ operator()(It x, It y)
+ {
+ if (comp(*x, *y))
+ return x;
+ else
+ return y;
+ }
+ };
/** @brief Reduction for finding the maximum element, using a comparator. */
template<typename Comp, typename It>
- struct max_element_reduct
- {
- Comp& comp;
+ struct max_element_reduct
+ {
+ Comp& comp;
- explicit max_element_reduct(Comp& c) : comp(c)
- { }
+ explicit
+ max_element_reduct(Comp& c) : comp(c) { }
- It
- operator()(It x, It y)
- {
- if (comp(*x, *y))
- return y;
- else
- return x;
- }
- };
+ It
+ operator()(It x, It y)
+ {
+ if (comp(*x, *y))
+ return y;
+ else
+ return x;
+ }
+ };
/** @brief General reduction, using a binary operator. */
template<typename BinOp>
- struct accumulate_binop_reduct
- {
- BinOp& binop;
+ struct accumulate_binop_reduct
+ {
+ BinOp& binop;
- explicit accumulate_binop_reduct(BinOp& b) : binop(b) {}
+ explicit
+ accumulate_binop_reduct(BinOp& b) : binop(b) { }
- template<typename Result, typename Addend>
- Result
- operator()(const Result& x, const Addend& y)
- { return binop(x, y); }
- };
+ template<typename Result, typename Addend>
+ Result
+ operator()(const Result& x, const Addend& y)
+ { return binop(x, y); }
+ };
}
#endif
// Smallest partitions.
for (int i = 1; i < (num_parts + 1 - size_greater); ++i)
{
- lengths[i-1] = size_part * range_length;
+ lengths[i - 1] = size_part * range_length;
index += size_part;
starts[i] = os_starts[index];
}
// Biggest partitions.
for (int i = num_parts + 1 - size_greater; i <= num_parts; ++i)
{
- lengths[i-1] = (size_part+1) * range_length;
+ lengths[i - 1] = (size_part+1) * range_length;
index += (size_part+1);
starts[i] = os_starts[index];
}
size = _size;
offset = size;
losers = new Loser[size];
- for (unsigned int l = 0; l < size; l++)
+ for (unsigned int l = 0; l < size; ++l)
{
//losers[l].key = ... stays unset
losers[l].inf = true;
bool inf = false;
for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
{
- if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup &&
- ((comp(losers[pos].key, key)) ||
- (!comp(key, losers[pos].key) && losers[pos].source < source)))
+ if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
+ && ((comp(losers[pos].key, key))
+ || (!comp(key, losers[pos].key)
+ && losers[pos].source < source)))
|| losers[pos].inf || sup)
{
// Take next key.
for (unsigned int pos = (offset + source) / 2; pos > 0; pos /= 2)
{
if ((!inf && !losers[pos].inf && !sup && !losers[pos].sup
- && ((comp(losers[pos].key, key)) ||
- (!comp(key, losers[pos].key) && losers[pos].source < source)))
+ && ((comp(losers[pos].key, key))
+ || (!comp(key, losers[pos].key)
+ && losers[pos].source < source)))
|| losers[pos].inf || sup)
{
std::swap(losers[pos].key, key);
{
unsigned int left = init_winner (2 * root);
unsigned int right = init_winner (2 * root + 1);
- if (losers[right].sup ||
- (!losers[left].sup
- && !comp(losers[right].key, losers[left].key)))
+ if (losers[right].sup
+ || (!losers[left].sup
+ && !comp(losers[right].key, losers[left].key)))
{
// Left one is less or equal.
losers[root] = losers[right];
unsigned int right = init_winner (2 * root + 1);
if (losers[right].sup
|| (!losers[left].sup
- && !comp(losers[right].key, losers[left].key)))
+ && !comp(losers[right].key, losers[left].key)))
{
// Left one is less or equal.
losers[root] = losers[right];
#ifndef COPY
keys = new T[ik];
#endif
- for (unsigned int i = ik - 1; i < k; i++)
+ for (unsigned int i = ik - 1; i < k; ++i)
losers[i + k].sup = true;
}
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
{
// The smaller one gets promoted, ties are broken by source.
- if ( (sup && (!losers[pos].sup || losers[pos].source < source)) ||
- (!sup && !losers[pos].sup &&
- ((comp(KEY(pos), KEY_SOURCE(source))) ||
- (!comp(KEY_SOURCE(source), KEY(pos))
- && losers[pos].source < source))))
+ if ((sup && (!losers[pos].sup || losers[pos].source < source))
+ || (!sup && !losers[pos].sup
+ && ((comp(KEY(pos), KEY_SOURCE(source)))
+ || (!comp(KEY_SOURCE(source), KEY(pos))
+ && losers[pos].source < source))))
{
// The other one is smaller.
std::swap(losers[pos].sup, sup);
k = 1 << (log2(ik - 1) + 1);
offset = k;
losers = new Loser[k * 2];
- for (unsigned int i = ik - 1; i < k; i++)
+ for (unsigned int i = ik - 1; i < k; ++i)
losers[i + k].sup = true;
}
for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
{
// The smaller one gets promoted, ties are broken by source.
- if ( (sup && (!losers[pos].sup || losers[pos].source < source)) ||
- (!sup && !losers[pos].sup &&
- ((comp(*losers[pos].keyp, *keyp)) ||
- (!comp(*keyp, *losers[pos].keyp)
- && losers[pos].source < source))))
+ if ( (sup && (!losers[pos].sup || losers[pos].source < source))
+ || (!sup && !losers[pos].sup &&
+ ((comp(*losers[pos].keyp, *keyp))
+ || (!comp(*keyp, *losers[pos].keyp)
+ && losers[pos].source < source))))
{
// The other one is smaller.
std::swap(losers[pos].sup, sup);
// Next greater or equal power of 2.
unsigned int division = 1 << (log2(end - begin - 1));
unsigned int left = init_winner(2 * root, begin, begin + division);
- unsigned int right
- = init_winner(2 * root + 1, begin + division, end);
+ unsigned int right = init_winner(2 * root + 1,
+ begin + division, end);
if (!comp(*losers[right].keyp, *losers[left].keyp))
{
// Left one is less or equal.
*target++ = *begin2++;
else
*target++ = *begin1++;
- max_length--;
+ --max_length;
}
if (begin1 != end1)
*target = element1;
- target++;
- max_length--;
+ ++target;
+ --max_length;
}
if (begin1 != end1)
{
difference_type localrank = rank * m / N ;
int j;
- for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); j++)
+ for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
a[sample[j].second] += n + 1;
for (; j < m; j++)
b[sample[j].second] -= n + 1;
if (b[i] < ns[i])
pq.push(std::make_pair(S(i)[b[i]], i));
- for (; skew != 0 && !pq.empty(); skew--)
+ for (; skew != 0 && !pq.empty(); --skew)
{
int source = pq.top().second;
pq.pop();
if (a[i] > 0)
pq.push(std::make_pair(S(i)[a[i] - 1], i));
- for (; skew != 0; skew++)
+ for (; skew != 0; ++skew)
{
int source = pq.top().second;
pq.pop();
ns[0] = std::distance(begin_seqs[0].first, begin_seqs[0].second);
nmax = ns[0];
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
ns[i] = std::distance(begin_seqs[i].first, begin_seqs[i].second);
nmax = std::max(nmax, ns[i]);
// From now on, including padding.
N = l * m;
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
a[i] = 0;
b[i] = l;
difference_type localrank = rank * m / N ;
int j;
- for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); j++)
+ for (j = 0; j < localrank && ((n + 1) <= ns[sample[j].second]); ++j)
a[sample[j].second] += n + 1;
- for (; j < m; j++)
+ for (; j < m; ++j)
b[sample[j].second] -= n + 1;
// Further refinement.
n /= 2;
const T* lmax = NULL;
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
if (a[i] > 0)
{
}
difference_type leftsize = 0, total = 0;
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
leftsize += a[i] / (n + 1);
total += l / (n + 1);
std::vector<std::pair<T, int> >,
lexicographic_reverse<T, int, Comparator> > pq(lrcomp);
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
if (b[i] < ns[i])
pq.push(std::make_pair(S(i)[b[i]], i));
std::vector<std::pair<T, int> >,
lexicographic<T, int, Comparator> > pq(lcomp);
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
if (a[i] > 0)
pq.push(std::make_pair(S(i)[a[i] - 1], i));
// Impossible to avoid the warning?
T maxleft, minright;
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
if (a[i] > 0)
{
// We have to calculate an offset.
offset = 0;
- for (int i = 0; i < m; i++)
+ for (int i = 0; i < m; ++i)
{
difference_type lb = std::lower_bound(S(i), S(i) + ns[i],
minright,
template<typename RandomAccessIterator, typename Comparator>
inline bool
operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ guarded_iterator<RandomAccessIterator, Comparator>& bi2);
/** @brief Iterator wrapper supporting an implicit supremum at the end
of the sequence, dominating all comparisons.
* @param end End iterator of sequence.
* @param comp Comparator provided for associated overloaded
* compare operators. */
- inline guarded_iterator(RandomAccessIterator begin,
- RandomAccessIterator end, Comparator& comp)
+ guarded_iterator(RandomAccessIterator begin,
+ RandomAccessIterator end, Comparator& comp)
: current(begin), end(end), comp(comp)
{ }
/** @brief Pre-increment operator.
* @return This. */
- inline guarded_iterator<RandomAccessIterator, Comparator>&
+ guarded_iterator<RandomAccessIterator, Comparator>&
operator++()
{
++current;
/** @brief Dereference operator.
* @return Referenced element. */
- inline typename std::iterator_traits<RandomAccessIterator>::value_type
+ typename std::iterator_traits<RandomAccessIterator>::value_type
operator*()
{ return *current; }
/** @brief Convert to wrapped iterator.
* @return Wrapped iterator. */
- inline operator RandomAccessIterator()
+ operator RandomAccessIterator()
{ return current; }
friend bool
operator< <RandomAccessIterator, Comparator>(
- guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ guarded_iterator<RandomAccessIterator, Comparator>& bi1,
+ guarded_iterator<RandomAccessIterator, Comparator>& bi2);
friend bool
operator<= <RandomAccessIterator, Comparator>(
- guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ guarded_iterator<RandomAccessIterator, Comparator>& bi1,
+ guarded_iterator<RandomAccessIterator, Comparator>& bi2);
};
/** @brief Compare two elements referenced by guarded iterators.
template<typename RandomAccessIterator, typename Comparator>
inline bool
operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
- guarded_iterator<RandomAccessIterator, Comparator>& bi2)
+ guarded_iterator<RandomAccessIterator, Comparator>& bi2)
{
if (bi2.current == bi2.end) //bi1 is sup
return bi1.current != bi1.end; //bi2 is not sup
* @param begin Begin iterator of sequence.
* @param end Unused, only for compatibility.
* @param comp Unused, only for compatibility. */
- inline unguarded_iterator(RandomAccessIterator begin,
- RandomAccessIterator end, Comparator& comp)
+ unguarded_iterator(RandomAccessIterator begin,
+ RandomAccessIterator end, Comparator& comp)
: current(begin), comp(comp)
{ }
/** @brief Pre-increment operator.
* @return This. */
- inline unguarded_iterator<RandomAccessIterator, Comparator>&
+ unguarded_iterator<RandomAccessIterator, Comparator>&
operator++()
{
++current;
/** @brief Dereference operator.
* @return Referenced element. */
- inline typename std::iterator_traits<RandomAccessIterator>::value_type
+ typename std::iterator_traits<RandomAccessIterator>::value_type
operator*()
{ return *current; }
/** @brief Convert to wrapped iterator.
* @return Wrapped iterator. */
- inline
operator RandomAccessIterator()
{ return current; }
friend bool
operator< <RandomAccessIterator, Comparator>(
- unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
+ unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
friend bool
operator<= <RandomAccessIterator, Comparator>(
- unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
- unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
+ unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
+ unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
};
/** @brief Compare two elements referenced by unguarded iterators.
* @param length Maximum length to merge.
* @param stable Unused, stable anyway.
* @return End iterator of output sequence. */
-template<
- template<typename RAI, typename C> class iterator,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<template<typename RAI, typename C> class iterator,
+ typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
- multiway_merge_3_variant(
- RandomAccessIteratorIterator seqs_begin,
- RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- Comparator comp, _DifferenceTp length, bool stable)
+ multiway_merge_3_variant(RandomAccessIteratorIterator seqs_begin,
+ RandomAccessIteratorIterator seqs_end,
+ RandomAccessIterator3 target,
+ Comparator comp, _DifferenceTp length,
+ bool stable)
{
_GLIBCXX_CALL(length);
return target;
}
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_3_combined(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
* @param length Maximum length to merge.
* @param stable Unused, stable anyway.
* @return End iterator of output sequence. */
-template<
- template<typename RAI, typename C> class iterator,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<template<typename RAI, typename C> class iterator,
+ typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
return target;
}
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_4_combined(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
* @param stable Stable merging incurs a performance penalty.
* @return End iterator of output sequence.
*/
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_bubble(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
++target;
++(seqs_begin[source[0]].first);
--length;
- if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
+ if (seqs_begin[source[0]].first
+ == seqs_begin[source[0]].second)
{
// Move everything to the left.
for (int s = 0; s < nrs - 1; ++s)
++target;
++(seqs_begin[source[0]].first);
--length;
- if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
+ if (seqs_begin[source[0]].first
+ == seqs_begin[source[0]].second)
{
for (int s = 0; s < nrs - 1; ++s)
{
// Sink down.
j = 1;
- while ((j < nrs) && (comp(fe[j], fe[j - 1]) ||
- (!comp(fe[j - 1], fe[j])
- && (source[j] < source[j - 1]))))
+ while ((j < nrs) && (comp(fe[j], fe[j - 1])
+ || (!comp(fe[j - 1], fe[j])
+ && (source[j] < source[j - 1]))))
{
std::swap(fe[j - 1], fe[j]);
std::swap(source[j - 1], source[j]);
++target;
++seqs_begin[source[0]].first;
--length;
- if (seqs_begin[source[0]].first == seqs_begin[source[0]].second)
+ if (seqs_begin[source[0]].first
+ == seqs_begin[source[0]].second)
{
for (int s = 0; s < (nrs - 1); ++s)
{
* @param stable Stable merging incurs a performance penalty.
* @return End iterator of output sequence.
*/
-template<
- typename LT,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename LT,
+ typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
for (int t = 0; t < k; ++t)
{
- if(arbitrary_element == NULL && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
+ if(arbitrary_element == NULL
+ && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
arbitrary_element = &(*seqs_begin[t].first);
total_length += _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]);
}
* @return End iterator of output sequence.
* @pre No input will run out of elements during the merge.
*/
-template<
- typename LT,
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp, typename Comparator>
+template<typename LT,
+ typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp, typename Comparator>
RandomAccessIterator3
multiway_merge_loser_tree_unguarded(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
return target;
}
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_loser_tree_combined(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
return target_end;
}
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_loser_tree_sentinel(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
- RandomAccessIterator3 target,
- Comparator comp,
- _DifferenceTp length, bool stable)
+ RandomAccessIterator3 target,
+ Comparator comp,
+ _DifferenceTp length, bool stable)
{
_GLIBCXX_CALL(length)
/** @brief Sequential multi-way merging switch.
*
- * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings.
+ * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and
+ * runtime settings.
* @param seqs_begin Begin iterator of iterator pair input sequence.
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param stable Stable merging incurs a performance penalty.
* @param sentinel The sequences have a sentinel element.
* @return End iterator of output sequence. */
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
{
case Settings::LOSER_TREE_COMBINED:
return_target = multiway_merge_3_combined(seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
case Settings::LOSER_TREE_SENTINEL:
- return_target = multiway_merge_3_variant<unguarded_iterator>(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target =
+ multiway_merge_3_variant<unguarded_iterator>(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
default:
- return_target = multiway_merge_3_variant<guarded_iterator>(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target =
+ multiway_merge_3_variant<guarded_iterator>(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
}
break;
switch (mwma)
{
case Settings::LOSER_TREE_COMBINED:
- return_target = multiway_merge_4_combined(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target = multiway_merge_4_combined(seqs_begin,
+ seqs_end,
+ target,
+ comp, length, stable);
break;
case Settings::LOSER_TREE_SENTINEL:
- return_target = multiway_merge_4_variant<unguarded_iterator>(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target =
+ multiway_merge_4_variant<unguarded_iterator>(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
default:
return_target = multiway_merge_4_variant<guarded_iterator>(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ seqs_begin,
+ seqs_end,
+ target,
+ comp, length, stable);
break;
}
break;
switch (mwma)
{
case Settings::BUBBLE:
- return_target = multiway_merge_bubble(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target = multiway_merge_bubble(seqs_begin,
+ seqs_end,
+ target,
+ comp, length, stable);
break;
#if _GLIBCXX_LOSER_TREE_EXPLICIT
case Settings::LOSER_TREE_EXPLICIT:
return_target = multiway_merge_loser_tree<
- LoserTreeExplicit<value_type, Comparator> >(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ LoserTreeExplicit<value_type, Comparator> >(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
#endif
#if _GLIBCXX_LOSER_TREE
case Settings::LOSER_TREE:
return_target = multiway_merge_loser_tree<
- LoserTree<value_type, Comparator> >(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ LoserTree<value_type, Comparator> >(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
#endif
#if _GLIBCXX_LOSER_TREE_COMBINED
case Settings::LOSER_TREE_COMBINED:
- return_target = multiway_merge_loser_tree_combined(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target = multiway_merge_loser_tree_combined(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
#endif
#if _GLIBCXX_LOSER_TREE_SENTINEL
case Settings::LOSER_TREE_SENTINEL:
- return_target = multiway_merge_loser_tree_sentinel(
- seqs_begin,
- seqs_end,
- target,
- comp, length, stable);
+ return_target = multiway_merge_loser_tree_sentinel(seqs_begin,
+ seqs_end,
+ target,
+ comp, length,
+ stable);
break;
#endif
default:
/** @brief Parallel multi-way merge routine.
*
- * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor and runtime settings.
+ * The _GLIBCXX_PARALLEL_DECISION if based on the branching factor
+ * and runtime settings.
* @param seqs_begin Begin iterator of iterator pair input sequence.
* @param seqs_end End iterator of iterator pair input sequence.
* @param target Begin iterator out output sequence.
* @param sentinel Ignored.
* @return End iterator of output sequence.
*/
-template<
- typename RandomAccessIteratorIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
RandomAccessIteratorIterator seqs_end,
std::vector<std::pair<difference_type, difference_type> >* pieces;
thread_index_t num_threads = static_cast<thread_index_t>(
- std::min<difference_type>(get_max_threads(), total_length));
+ std::min<difference_type>(get_max_threads(), total_length));
# pragma omp parallel num_threads (num_threads)
{
for (difference_type i = 0; i < num_samples; ++i)
{
difference_type sample_index =
- static_cast<difference_type>(
- _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s]) * (double(i + 1) /
- (num_samples + 1)) * (double(length)
- / total_length));
- ::new(&(samples[s * num_samples + i])) value_type(
- seqs_begin[s].first[sample_index]);
+ static_cast<difference_type>(
+ _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
+ * (double(i + 1) / (num_samples + 1))
+ * (double(length) / total_length));
+ ::new(&(samples[s * num_samples + i]))
+ value_type(seqs_begin[s].first[sample_index]);
}
if (stable)
- __gnu_sequential::stable_sort(
- samples, samples + (num_samples * k), comp);
+ __gnu_sequential::stable_sort(samples, samples
+ + (num_samples * k), comp);
else
- __gnu_sequential::sort(
- samples, samples + (num_samples * k), comp);
+ __gnu_sequential::sort(samples, samples
+ + (num_samples * k), comp);
for (int slab = 0; slab < num_threads; ++slab)
// For each slab / processor.
// For each sequence.
if (slab > 0)
pieces[slab][seq].first =
- std::upper_bound(
- seqs_begin[seq].first,
- seqs_begin[seq].second,
- samples[num_samples * k * slab / num_threads],
- comp)
- - seqs_begin[seq].first;
+ std::upper_bound(seqs_begin[seq].first,
+ seqs_begin[seq].second,
+ samples[num_samples * k
+ * slab / num_threads],
+ comp)
+ - seqs_begin[seq].first;
else
{
// Absolute beginning.
}
if ((slab + 1) < num_threads)
pieces[slab][seq].second =
- std::upper_bound(
- seqs_begin[seq].first,
- seqs_begin[seq].second,
- samples[num_samples * k * (slab + 1) /
- num_threads], comp)
- - seqs_begin[seq].first;
+ std::upper_bound(seqs_begin[seq].first,
+ seqs_begin[seq].second,
+ samples[num_samples * k
+ * (slab + 1)
+ / num_threads], comp)
+ - seqs_begin[seq].first;
else
- pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
+ pieces[slab][seq].second
+ = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
}
::operator delete(samples);
}
{
offsets[num_threads - 1].resize(k);
multiseq_partition(se.begin(), se.end(),
- difference_type(length),
- offsets[num_threads - 1].begin(), comp);
+ difference_type(length),
+ offsets[num_threads - 1].begin(),
+ comp);
}
}
pieces[slab - 1][seq].second;
if (!tight || slab < (num_threads - 1))
pieces[slab][seq].second =
- offsets[slab][seq] - seqs_begin[seq].first;
+ offsets[slab][seq] - seqs_begin[seq].first;
else
{
// slab == num_threads - 1
pieces[slab][seq].second =
- _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
+ _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
}
}
}
for (int s = 0; s < k; ++s)
{
chunks[s] = std::make_pair(
- seqs_begin[s].first + pieces[iam][s].first,
- seqs_begin[s].first + pieces[iam][s].second);
+ seqs_begin[s].first + pieces[iam][s].first,
+ seqs_begin[s].first + pieces[iam][s].second);
local_length += _GLIBCXX_PARALLEL_LENGTH(chunks[s]);
}
begin0 = seqs_begin[0].first + pieces[iam][0].first,
begin1 = seqs_begin[1].first + pieces[iam][1].first;
merge_advance(begin0,
- seqs_begin[0].first + pieces[iam][0].second,
- begin1,
- seqs_begin[1].first + pieces[iam][1].second,
- target + target_position,
- (pieces[iam][0].second - pieces[iam][0].first) +
- (pieces[iam][1].second - pieces[iam][1].first),
- comp);
+ seqs_begin[0].first + pieces[iam][0].second,
+ begin1,
+ seqs_begin[1].first + pieces[iam][1].second,
+ target + target_position,
+ (pieces[iam][0].second - pieces[iam][0].first) +
+ (pieces[iam][1].second - pieces[iam][1].first),
+ comp);
}
} //parallel
* @param stable Stable merging incurs a performance penalty.
* @return End iterator of output sequence.
*/
-template<
- typename RandomAccessIteratorPairIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorPairIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge(RandomAccessIteratorPairIterator seqs_begin,
RandomAccessIteratorPairIterator seqs_end,
if (_GLIBCXX_PARALLEL_CONDITION(
((seqs_end - seqs_begin) >= Settings::multiway_merge_minimal_k)
&& ((sequence_index_t)length >= Settings::multiway_merge_minimal_n)))
- target_end = parallel_multiway_merge(
- seqs_begin, seqs_end,
- target, comp, static_cast<difference_type>(length), stable, false);
+ target_end = parallel_multiway_merge(seqs_begin, seqs_end,
+ target, comp,
+ static_cast<difference_type>(length),
+ stable, false);
else
- target_end = multiway_merge(
- seqs_begin, seqs_end,
- target, comp, length, stable, false, sequential_tag());
+ target_end = multiway_merge(seqs_begin, seqs_end, target, comp, length,
+ stable, false, sequential_tag());
return target_end;
}
* @pre For each @c i, @c seqs_begin[i].second must be the end
* marker of the sequence, but also reference the one more sentinel
* element. */
-template<
- typename RandomAccessIteratorPairIterator,
- typename RandomAccessIterator3,
- typename _DifferenceTp,
- typename Comparator>
+template<typename RandomAccessIteratorPairIterator,
+ typename RandomAccessIterator3,
+ typename _DifferenceTp,
+ typename Comparator>
RandomAccessIterator3
multiway_merge_sentinel(RandomAccessIteratorPairIterator seqs_begin,
RandomAccessIteratorPairIterator seqs_end,
seqs_begin, seqs_end,
target, comp, static_cast<difference_type>(length), stable, true);
else
- return multiway_merge(
- seqs_begin, seqs_end,
- target, comp, length, stable, true, sequential_tag());
+ return multiway_merge(seqs_begin, seqs_end,
+ target, comp, length, stable,
+ true, sequential_tag());
}
}
* @param num_samples Number of samples to select.
*/
template<typename RandomAccessIterator, typename _DifferenceTp>
- inline void
+ void
determine_samples(PMWMSSortingData<RandomAccessIterator>* sd,
_DifferenceTp& num_samples)
{
equally_split(sd->starts[iam + 1] - sd->starts[iam],
num_samples + 1, es);
- for (difference_type i = 0; i < num_samples; i++)
- ::new(&(sd->samples[iam * num_samples + i])) value_type(
- sd->source[sd->starts[iam] + es[i + 1]]);
+ for (difference_type i = 0; i < num_samples; ++i)
+ ::new(&(sd->samples[iam * num_samples + i]))
+ value_type(sd->source[sd->starts[iam] + es[i + 1]]);
delete[] es;
}
* @param comp Comparator.
*/
template<typename RandomAccessIterator, typename Comparator>
- inline void
+ void
parallel_sort_mwms_pu(PMWMSSortingData<RandomAccessIterator>* sd,
Comparator& comp)
{
# pragma omp barrier
- for (int s = 0; s < sd->num_threads; s++)
+ for (int s = 0; s < sd->num_threads; ++s)
{
// For each sequence.
if (num_samples * iam > 0)
std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> >
seqs(sd->num_threads);
- for (int s = 0; s < sd->num_threads; s++)
+ for (int s = 0; s < sd->num_threads; ++s)
seqs[s] = std::make_pair(sd->sorting_places[s],
sd->sorting_places[s]
+ (sd->starts[s + 1] - sd->starts[s]));
multiseq_partition(seqs.begin(), seqs.end(),
sd->starts[iam + 1], offsets.begin(), comp);
- for (int seq = 0; seq < sd->num_threads; seq++)
+ for (int seq = 0; seq < sd->num_threads; ++seq)
{
// for each sequence
if (iam < (sd->num_threads - 1))
sd->pieces[iam][seq].end = offsets[seq] - seqs[seq].first;
else
// very end of this sequence
- sd->pieces[iam][seq].end =
- sd->starts[seq + 1] - sd->starts[seq];
+ sd->pieces[iam][seq].end = (sd->starts[seq + 1]
+ - sd->starts[seq]);
}
# pragma omp barrier
- for (int seq = 0; seq < sd->num_threads; seq++)
+ for (int seq = 0; seq < sd->num_threads; ++seq)
{
// For each sequence.
if (iam > 0)
// Offset from target begin, length after merging.
difference_type offset = 0, length_am = 0;
- for (int s = 0; s < sd->num_threads; s++)
+ for (int s = 0; s < sd->num_threads; ++s)
{
length_am += sd->pieces[iam][s].end - sd->pieces[iam][s].begin;
offset += sd->pieces[iam][s].begin;
// instead of the assignment operator.
// XXX incorrect (de)construction
sd->merging_places[iam] = sd->temporaries[iam] =
- static_cast<value_type*>(
- ::operator new(sizeof(value_type) * length_am));
+ static_cast<value_type*>(::operator new(sizeof(value_type)
+ * length_am));
#else
// Merge directly to target.
sd->merging_places[iam] = sd->source + offset;
std::vector<std::pair<SortingPlacesIterator, SortingPlacesIterator> >
seqs(sd->num_threads);
- for (int s = 0; s < sd->num_threads; s++)
+ for (int s = 0; s < sd->num_threads; ++s)
{
seqs[s] =
- std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin,
- sd->sorting_places[s] + sd->pieces[iam][s].end);
+ std::make_pair(sd->sorting_places[s] + sd->pieces[iam][s].begin,
+ sd->sorting_places[s] + sd->pieces[iam][s].end);
}
multiway_merge(seqs.begin(), seqs.end(), sd->merging_places[iam], comp,
* @param stable Stable sorting.
*/
template<typename RandomAccessIterator, typename Comparator>
- inline void
+ void
parallel_sort_mwms(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp,
- typename std::iterator_traits<RandomAccessIterator>
- ::difference_type n,
- int num_threads,
- bool stable)
+ Comparator comp, typename
+ std::iterator_traits<RandomAccessIterator>::
+ difference_type n, int num_threads, bool stable)
{
_GLIBCXX_CALL(n)
(Settings::sort_mwms_oversampling * num_threads - 1)
* num_threads;
sd.samples = static_cast<value_type*>(
- ::operator new(size * sizeof(value_type)));
+ ::operator new(size * sizeof(value_type)));
}
else
sd.samples = NULL;
sd.offsets = new difference_type[num_threads - 1];
sd.pieces = new std::vector<Piece<difference_type> >[num_threads];
- for (int s = 0; s < num_threads; s++)
+ for (int s = 0; s < num_threads; ++s)
sd.pieces[s].resize(num_threads);
starts = sd.starts = new difference_type[num_threads + 1];
sd.stable = stable;
difference_type chunk_length = n / num_threads;
difference_type split = n % num_threads;
difference_type pos = 0;
- for (int i = 0; i < num_threads; i++)
+ for (int i = 0; i < num_threads; ++i)
{
starts[i] = pos;
pos += (i < split) ? (chunk_length + 1) : chunk_length;
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
{
// Sequential fallback.
template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::accumulate(begin, end, init); }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::accumulate(begin, end, init); }
template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::accumulate(begin, end, init, binary_op); }
// Sequential fallback for input iterator case.
template<typename InputIterator, typename T, typename IteratorTag>
- inline T
- accumulate_switch(InputIterator begin, InputIterator end, T init, IteratorTag) { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
-
- template<typename InputIterator, typename T, typename BinaryOperation, typename IteratorTag>
- T
- accumulate_switch(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op, IteratorTag)
- {
- return accumulate(begin, end, init, binary_op,
- __gnu_parallel::sequential_tag());
- }
+ inline T
+ accumulate_switch(InputIterator begin, InputIterator end,
+ T init, IteratorTag)
+ { return accumulate(begin, end, init, __gnu_parallel::sequential_tag()); }
+
+ template<typename InputIterator, typename T, typename BinaryOperation,
+ typename IteratorTag>
+ T
+ accumulate_switch(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op, IteratorTag)
+ { return accumulate(begin, end, init, binary_op,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename _RandomAccessIterator, typename T, typename BinaryOperation>
- T
- accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
- T init, BinaryOperation binary_op,
- random_access_iterator_tag,
- __gnu_parallel::parallelism parallelism_tag
- = __gnu_parallel::parallel_unbalanced)
- {
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
- {
- T res = init;
- __gnu_parallel::accumulate_selector<_RandomAccessIterator> my_selector;
- __gnu_parallel::for_each_template_random_access(begin, end, __gnu_parallel::nothing(), my_selector, __gnu_parallel::accumulate_binop_reduct<BinaryOperation>(binary_op), res, res, -1, parallelism_tag);
- return res;
- }
- else
- return accumulate(begin, end, init, binary_op,
- __gnu_parallel::sequential_tag());
- }
+ template<typename _RandomAccessIterator, typename T,
+ typename BinaryOperation>
+ T
+ accumulate_switch(_RandomAccessIterator begin, _RandomAccessIterator end,
+ T init, BinaryOperation binary_op,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
+ {
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::accumulate_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
+ {
+ T res = init;
+ __gnu_parallel::accumulate_selector<_RandomAccessIterator>
+ my_selector;
+ __gnu_parallel::
+ for_each_template_random_access(begin, end,
+ __gnu_parallel::nothing(),
+ my_selector,
+ __gnu_parallel::
+ accumulate_binop_reduct
+ <BinaryOperation>(binary_op),
+ res, res, -1, parallelism_tag);
+ return res;
+ }
+ else
+ return accumulate(begin, end, init, binary_op,
+ __gnu_parallel::sequential_tag());
+ }
// Public interface.
template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::iterator_category iterator_category;
-
- return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
- iterator_category(), parallelism_tag);
- }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef std::iterator_traits<InputIterator> iterator_traits;
+ typedef typename iterator_traits::value_type value_type;
+ typedef typename iterator_traits::iterator_category iterator_category;
+
+ return accumulate_switch(begin, end, init,
+ __gnu_parallel::plus<T, value_type>(),
+ iterator_category(), parallelism_tag);
+ }
template<typename InputIterator, typename T>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init)
- {
- typedef std::iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::iterator_category iterator_category;
-
- return accumulate_switch(begin, end, init, __gnu_parallel::plus<T, value_type>(),
- iterator_category());
- }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init)
+ {
+ typedef std::iterator_traits<InputIterator> iterator_traits;
+ typedef typename iterator_traits::value_type value_type;
+ typedef typename iterator_traits::iterator_category iterator_category;
+
+ return accumulate_switch(begin, end, init,
+ __gnu_parallel::plus<T, value_type>(),
+ iterator_category());
+ }
template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return accumulate_switch(begin, end, init, binary_op,
- iterator_category(), parallelism_tag);
- }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef iterator_traits<InputIterator> iterator_traits;
+ typedef typename iterator_traits::iterator_category iterator_category;
+ return accumulate_switch(begin, end, init, binary_op,
+ iterator_category(), parallelism_tag);
+ }
template<typename InputIterator, typename T, typename BinaryOperation>
- inline T
- accumulate(InputIterator begin, InputIterator end, T init,
- BinaryOperation binary_op)
- {
- typedef iterator_traits<InputIterator> iterator_traits;
- typedef typename iterator_traits::iterator_category iterator_category;
- return accumulate_switch(begin, end, init, binary_op,
- iterator_category());
- }
+ inline T
+ accumulate(InputIterator begin, InputIterator end, T init,
+ BinaryOperation binary_op)
+ {
+ typedef iterator_traits<InputIterator> iterator_traits;
+ typedef typename iterator_traits::iterator_category iterator_category;
+ return accumulate_switch(begin, end, init, binary_op,
+ iterator_category());
+ }
// Sequential fallback.
template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); }
-
- template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init,
- binary_op1, binary_op2);
- }
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init); }
+
+ template<typename InputIterator1, typename InputIterator2, typename T,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init, BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::inner_product(first1, last1, first2, init,
+ binary_op1, binary_op2); }
// Parallel algorithm for random access iterators.
- template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- T
- inner_product_switch(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, T init, BinaryFunction1 binary_op1, BinaryFunction2 binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
- {
- if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1) >= __gnu_parallel::Settings::accumulate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
- {
- T res = init;
- __gnu_parallel::inner_product_selector<RandomAccessIterator1, RandomAccessIterator2, T> my_selector(first1, first2);
- __gnu_parallel::for_each_template_random_access(first1, last1, binary_op2, my_selector, binary_op1, res, res, -1, parallelism_tag);
- return res;
- }
- else
- return inner_product(first1, last1, first2, init,
- __gnu_parallel::sequential_tag());
- }
+ template<typename RandomAccessIterator1, typename RandomAccessIterator2,
+ typename T, typename BinaryFunction1, typename BinaryFunction2>
+ T
+ inner_product_switch(RandomAccessIterator1 first1,
+ RandomAccessIterator1 last1,
+ RandomAccessIterator2 first2, T init,
+ BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_unbalanced)
+ {
+ if (_GLIBCXX_PARALLEL_CONDITION((last1 - first1)
+ >= __gnu_parallel::Settings::
+ accumulate_minimal_n
+ && __gnu_parallel::
+ is_parallel(parallelism_tag)))
+ {
+ T res = init;
+ __gnu_parallel::
+ inner_product_selector<RandomAccessIterator1,
+ RandomAccessIterator2, T> my_selector(first1, first2);
+ __gnu_parallel::
+ for_each_template_random_access(first1, last1, binary_op2,
+ my_selector, binary_op1,
+ res, res, -1, parallelism_tag);
+ return res;
+ }
+ else
+ return inner_product(first1, last1, first2, init,
+ __gnu_parallel::sequential_tag());
+ }
// No parallelism for input iterators.
- template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2, typename IteratorTag1, typename IteratorTag2>
- inline T
- inner_product_switch(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init,
- BinaryFunction1 binary_op1, BinaryFunction2 binary_op2,
- IteratorTag1, IteratorTag2)
- {
- return inner_product(first1, last1, first2, init, binary_op1, binary_op2,
- __gnu_parallel::sequential_tag());
- }
-
- template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
-
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
-
- return inner_product_switch(first1, last1, first2, init, binary_op1,
- binary_op2, iterator1_category(),
- iterator2_category(), parallelism_tag);
- }
-
- template<typename InputIterator1, typename InputIterator2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init, BinaryFunction1 binary_op1,
- BinaryFunction2 binary_op2)
- {
- typedef iterator_traits<InputIterator1> traits1_type;
- typedef typename traits1_type::iterator_category iterator1_category;
-
- typedef iterator_traits<InputIterator2> traits2_type;
- typedef typename traits2_type::iterator_category iterator2_category;
-
- return inner_product_switch(first1, last1, first2, init, binary_op1,
- binary_op2, iterator1_category(),
- iterator2_category());
- }
+ template<typename InputIterator1, typename InputIterator2, typename T,
+ typename BinaryFunction1, typename BinaryFunction2,
+ typename IteratorTag1, typename IteratorTag2>
+ inline T
+ inner_product_switch(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init,
+ BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2,
+ IteratorTag1, IteratorTag2)
+ { return inner_product(first1, last1, first2, init,
+ binary_op1, binary_op2,
+ __gnu_parallel::sequential_tag()); }
+
+ template<typename InputIterator1, typename InputIterator2, typename T,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init, BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef iterator_traits<InputIterator1> traits1_type;
+ typedef typename traits1_type::iterator_category iterator1_category;
+
+ typedef iterator_traits<InputIterator2> traits2_type;
+ typedef typename traits2_type::iterator_category iterator2_category;
+
+ return inner_product_switch(first1, last1, first2, init, binary_op1,
+ binary_op2, iterator1_category(),
+ iterator2_category(), parallelism_tag);
+ }
+
+ template<typename InputIterator1, typename InputIterator2, typename T,
+ typename BinaryFunction1, typename BinaryFunction2>
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init, BinaryFunction1 binary_op1,
+ BinaryFunction2 binary_op2)
+ {
+ typedef iterator_traits<InputIterator1> traits1_type;
+ typedef typename traits1_type::iterator_category iterator1_category;
+
+ typedef iterator_traits<InputIterator2> traits2_type;
+ typedef typename traits2_type::iterator_category iterator2_category;
+
+ return inner_product_switch(first1, last1, first2, init, binary_op1,
+ binary_op2, iterator1_category(),
+ iterator2_category());
+ }
template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef iterator_traits<InputIterator1> traits_type1;
- typedef typename traits_type1::value_type value_type1;
- typedef iterator_traits<InputIterator2> traits_type2;
- typedef typename traits_type2::value_type value_type2;
-
- typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef iterator_traits<InputIterator1> traits_type1;
+ typedef typename traits_type1::value_type value_type1;
+ typedef iterator_traits<InputIterator2> traits_type2;
+ typedef typename traits_type2::value_type value_type2;
+
+ typedef typename
+ __gnu_parallel::multiplies<value_type1, value_type2>::result
multiplies_result_type;
- return inner_product(first1, last1, first2, init,
+ return inner_product(first1, last1, first2, init,
__gnu_parallel::plus<T, multiplies_result_type>(),
- __gnu_parallel::multiplies<value_type1, value_type2>(),
+ __gnu_parallel::
+ multiplies<value_type1, value_type2>(),
parallelism_tag);
- }
+ }
template<typename InputIterator1, typename InputIterator2, typename T>
- inline T
- inner_product(InputIterator1 first1, InputIterator1 last1,
- InputIterator2 first2, T init)
- {
- typedef iterator_traits<InputIterator1> traits_type1;
- typedef typename traits_type1::value_type value_type1;
- typedef iterator_traits<InputIterator2> traits_type2;
- typedef typename traits_type2::value_type value_type2;
-
- typedef typename __gnu_parallel::multiplies<value_type1, value_type2>::result
+ inline T
+ inner_product(InputIterator1 first1, InputIterator1 last1,
+ InputIterator2 first2, T init)
+ {
+ typedef iterator_traits<InputIterator1> traits_type1;
+ typedef typename traits_type1::value_type value_type1;
+ typedef iterator_traits<InputIterator2> traits_type2;
+ typedef typename traits_type2::value_type value_type2;
+
+ typedef typename
+ __gnu_parallel::multiplies<value_type1, value_type2>::result
multiplies_result_type;
- return inner_product(first1, last1, first2, init,
+ return inner_product(first1, last1, first2, init,
__gnu_parallel::plus<T, multiplies_result_type>(),
- __gnu_parallel::multiplies<value_type1, value_type2>());
- }
+ __gnu_parallel::
+ multiplies<value_type1, value_type2>());
+ }
// Sequential fallback.
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::partial_sum(begin, end, result); }
+ inline OutputIterator
+ partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::partial_sum(begin, end, result); }
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- BinaryOperation bin_op, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ inline OutputIterator
+ partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
+ BinaryOperation bin_op, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation, typename IteratorTag1, typename IteratorTag2>
- inline OutputIterator
- partial_sum_switch(InputIterator begin, InputIterator end, OutputIterator result, BinaryOperation bin_op, IteratorTag1, IteratorTag2)
- {
- return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op);
- }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation, typename IteratorTag1,
+ typename IteratorTag2>
+ inline OutputIterator
+ partial_sum_switch(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ IteratorTag1, IteratorTag2)
+ { return _GLIBCXX_STD_P::partial_sum(begin, end, result, bin_op); }
// Parallel algorithm for random access iterators.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- OutputIterator
- partial_sum_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- random_access_iterator_tag, random_access_iterator_tag)
- {
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partial_sum_minimal_n))
- return __gnu_parallel::parallel_partial_sum(begin, end, result, bin_op);
- else
- return partial_sum(begin, end, result, bin_op, __gnu_parallel::sequential_tag());
- }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ OutputIterator
+ partial_sum_switch(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ random_access_iterator_tag, random_access_iterator_tag)
+ {
+ if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::
+ sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::
+ partial_sum_minimal_n))
+ return __gnu_parallel::parallel_partial_sum(begin, end,
+ result, bin_op);
+ else
+ return partial_sum(begin, end, result, bin_op,
+ __gnu_parallel::sequential_tag());
+ }
// Public interface.
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result)
- {
- typedef typename iterator_traits<InputIterator>::value_type value_type;
- return partial_sum(begin, end, result, std::plus<value_type>());
- }
+ inline OutputIterator
+ partial_sum(InputIterator begin, InputIterator end, OutputIterator result)
+ {
+ typedef typename iterator_traits<InputIterator>::value_type value_type;
+ return partial_sum(begin, end, result, std::plus<value_type>());
+ }
// Public interface
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
- BinaryOperation binary_op)
- {
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
-
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
-
- return partial_sum_switch(begin, end, result, binary_op,
- iteratori_category(), iteratoro_category());
- }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ inline OutputIterator
+ partial_sum(InputIterator begin, InputIterator end, OutputIterator result,
+ BinaryOperation binary_op)
+ {
+ typedef iterator_traits<InputIterator> traitsi_type;
+ typedef typename traitsi_type::iterator_category iteratori_category;
+
+ typedef iterator_traits<OutputIterator> traitso_type;
+ typedef typename traitso_type::iterator_category iteratoro_category;
+
+ return partial_sum_switch(begin, end, result, binary_op,
+ iteratori_category(), iteratoro_category());
+ }
// Sequential fallback.
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, __gnu_parallel::sequential_tag)
- { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); }
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result, __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result); }
// Sequential fallback.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- __gnu_parallel::sequential_tag)
- {
- return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op);
- }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ __gnu_parallel::sequential_tag)
+ { return _GLIBCXX_STD_P::adjacent_difference(begin, end, result, bin_op); }
// Sequential fallback for input iterator case.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation, typename IteratorTag1, typename IteratorTag2>
- inline OutputIterator
- adjacent_difference_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation, typename IteratorTag1,
+ typename IteratorTag2>
+ inline OutputIterator
+ adjacent_difference_switch(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
IteratorTag1, IteratorTag2)
- {
- return adjacent_difference(begin, end, result, bin_op,
- __gnu_parallel::sequential_tag());
- }
+ { return adjacent_difference(begin, end, result, bin_op,
+ __gnu_parallel::sequential_tag()); }
// Parallel algorithm for random access iterators.
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- OutputIterator
- adjacent_difference_switch(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::parallelism parallelism_tag
- = __gnu_parallel::parallel_balanced)
- {
- if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::adjacent_difference_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
- {
- bool dummy = true;
- typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator, random_access_iterator_tag> ip;
- *result = *begin;
- ip begin_pair(begin + 1, result + 1), end_pair(end, result + (end - begin));
- __gnu_parallel::adjacent_difference_selector<ip> functionality;
- __gnu_parallel::for_each_template_random_access(begin_pair, end_pair, bin_op, functionality, __gnu_parallel::dummy_reduct(), dummy, dummy, -1, parallelism_tag);
- return functionality.finish_iterator;
- }
- else
- return adjacent_difference(begin, end, result, bin_op,
- __gnu_parallel::sequential_tag());
- }
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ OutputIterator
+ adjacent_difference_switch(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism parallelism_tag
+ = __gnu_parallel::parallel_balanced)
+ {
+ if (_GLIBCXX_PARALLEL_CONDITION(
+ static_cast<__gnu_parallel::sequence_index_t>(end - begin)
+ >= __gnu_parallel::Settings::adjacent_difference_minimal_n
+ && __gnu_parallel::is_parallel(parallelism_tag)))
+ {
+ bool dummy = true;
+ typedef __gnu_parallel::iterator_pair<InputIterator, OutputIterator,
+ random_access_iterator_tag> ip;
+ *result = *begin;
+ ip begin_pair(begin + 1, result + 1),
+ end_pair(end, result + (end - begin));
+ __gnu_parallel::adjacent_difference_selector<ip> functionality;
+ __gnu_parallel::
+ for_each_template_random_access(begin_pair, end_pair, bin_op,
+ functionality,
+ __gnu_parallel::dummy_reduct(),
+ dummy, dummy, -1, parallelism_tag);
+ return functionality.finish_iterator;
+ }
+ else
+ return adjacent_difference(begin, end, result, bin_op,
+ __gnu_parallel::sequential_tag());
+ }
// Public interface.
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- return adjacent_difference(begin, end, result, std::minus<value_type>(),
- parallelism_tag);
- }
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef iterator_traits<InputIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ return adjacent_difference(begin, end, result, std::minus<value_type>(),
+ parallelism_tag);
+ }
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result)
- {
- typedef iterator_traits<InputIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- return adjacent_difference(begin, end, result, std::minus<value_type>());
- }
-
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation binary_op,
- __gnu_parallel::parallelism parallelism_tag)
- {
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
-
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
-
- return adjacent_difference_switch(begin, end, result, binary_op,
- iteratori_category(),
- iteratoro_category(), parallelism_tag);
- }
-
- template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
- inline OutputIterator
- adjacent_difference(InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation binary_op)
- {
- typedef iterator_traits<InputIterator> traitsi_type;
- typedef typename traitsi_type::iterator_category iteratori_category;
-
- typedef iterator_traits<OutputIterator> traitso_type;
- typedef typename traitso_type::iterator_category iteratoro_category;
-
- return adjacent_difference_switch(begin, end, result, binary_op,
- iteratori_category(),
- iteratoro_category());
- }
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result)
+ {
+ typedef iterator_traits<InputIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ return adjacent_difference(begin, end, result, std::minus<value_type>());
+ }
+
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation binary_op,
+ __gnu_parallel::parallelism parallelism_tag)
+ {
+ typedef iterator_traits<InputIterator> traitsi_type;
+ typedef typename traitsi_type::iterator_category iteratori_category;
+
+ typedef iterator_traits<OutputIterator> traitso_type;
+ typedef typename traitso_type::iterator_category iteratoro_category;
+
+ return adjacent_difference_switch(begin, end, result, binary_op,
+ iteratori_category(),
+ iteratoro_category(), parallelism_tag);
+ }
+
+ template<typename InputIterator, typename OutputIterator,
+ typename BinaryOperation>
+ inline OutputIterator
+ adjacent_difference(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation binary_op)
+ {
+ typedef iterator_traits<InputIterator> traitsi_type;
+ typedef typename traitsi_type::iterator_category iteratori_category;
+
+ typedef iterator_traits<OutputIterator> traitso_type;
+ typedef typename traitso_type::iterator_category iteratoro_category;
+
+ return adjacent_difference_switch(begin, end, result, binary_op,
+ iteratori_category(),
+ iteratoro_category());
+ }
} // end namespace
} // end namespace
// <numeric> parallel extensions -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
{
namespace __parallel
{
- template<typename _IIter, typename T>
- inline T
- accumulate(_IIter, _IIter, T);
-
- template<typename _IIter, typename T>
- inline T
- accumulate(_IIter, _IIter, T, __gnu_parallel::sequential_tag);
-
- template<typename _IIter, typename T>
- inline T
- accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism parallelism_tag);
-
- template<typename _IIter, typename T, typename _Tag>
- inline T
- accumulate_switch(_IIter, _IIter, T, _Tag);
-
- template<typename _IIter, typename T, typename _BinaryOper>
- inline T
- accumulate(_IIter, _IIter, T, _BinaryOper);
-
- template<typename _IIter, typename T, typename _BinaryOper>
- inline T
- accumulate(_IIter, _IIter, T, _BinaryOper, __gnu_parallel::sequential_tag);
-
- template<typename _IIter, typename T, typename _BinaryOper>
- inline T
- accumulate(_IIter, _IIter, T, _BinaryOper,
- __gnu_parallel::parallelism parallelism_tag);
-
- template<typename _IIter, typename T, typename _BinaryOper, typename _Tag>
- T
- accumulate_switch(_IIter, _IIter, T, _BinaryOper, _Tag);
-
- template<typename _RAIter, typename T, typename _BinaryOper>
- T
- accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
- random_access_iterator_tag, __gnu_parallel::parallelism);
-
+ template<typename _IIter, typename _Tp>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp);
+
+ template<typename _IIter, typename _Tp>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag);
+
+ template<typename _IIter, typename _Tp>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp, __gnu_parallel::parallelism);
+
+ template<typename _IIter, typename _Tp, typename _Tag>
+ _Tp
+ accumulate_switch(_IIter, _IIter, _Tp, _Tag);
+
+ template<typename _IIter, typename _Tp, typename _BinaryOper>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp, _BinaryOper);
+
+ template<typename _IIter, typename _Tp, typename _BinaryOper>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp, _BinaryOper,
+ __gnu_parallel::sequential_tag);
+
+ template<typename _IIter, typename _Tp, typename _BinaryOper>
+ _Tp
+ accumulate(_IIter, _IIter, _Tp, _BinaryOper,
+ __gnu_parallel::parallelism);
+
+ template<typename _IIter, typename _Tp, typename _BinaryOper,
+ typename _Tag>
+ _Tp
+ accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag);
+
+ template<typename _RAIter, typename _Tp, typename _BinaryOper>
+ _Tp
+ accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
- template<typename _IIter, typename _OIter>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter);
+ template<typename _IIter, typename _OIter>
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper);
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper);
template<typename _IIter, typename _OIter>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter,
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
- __gnu_parallel::sequential_tag);
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::parallelism);
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter,
+ __gnu_parallel::parallelism);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- inline _OIter
- adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
- __gnu_parallel::parallelism);
+ _OIter
+ adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper,
+ __gnu_parallel::parallelism);
- template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2>
- inline _OIter
- adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
+ template<typename _IIter, typename _OIter, typename _BinaryOper,
+ typename _Tag1, typename _Tag2>
+ _OIter
+ adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- _OIter
- adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
- random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::parallelism);
-
-
- template<typename _IIter1, typename _IIter2, typename T>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T);
-
- template<typename _IIter1, typename _IIter2, typename T>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::sequential_tag);
-
- template<typename _IIter1, typename _IIter2, typename T>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, __gnu_parallel::parallelism);
-
-
- template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2);
-
- template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
- __gnu_parallel::sequential_tag);
-
- template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- inline T
- inner_product(_IIter1, _IIter1, _IIter2, T, BinaryFunction1, BinaryFunction2,
- __gnu_parallel::parallelism);
-
- template<typename _RAIter1, typename _RAIter2, typename T, typename BinaryFunction1, typename BinaryFunction2>
- T
- inner_product_switch(_RAIter1, _RAIter1, _RAIter2, T, BinaryFunction1,
- BinaryFunction2, random_access_iterator_tag,
- random_access_iterator_tag,
- __gnu_parallel::parallelism);
-
- template<typename _IIter1, typename _IIter2, typename T, typename BinaryFunction1, typename BinaryFunction2, typename _Tag1, typename _Tag2>
- inline T
- inner_product_switch(_IIter1, _IIter1, _IIter2, T, BinaryFunction1,
- BinaryFunction2, _Tag1, _Tag2);
+ _OIter
+ adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp,
+ __gnu_parallel::sequential_tag);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp,
+ __gnu_parallel::parallelism);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename _BinaryFunction1, typename _BinaryFunction2>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp,
+ _BinaryFunction1, _BinaryFunction2);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename _BinaryFunction1, typename _BinaryFunction2>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
+ _BinaryFunction2, __gnu_parallel::sequential_tag);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2>
+ _Tp
+ inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1,
+ BinaryFunction2, __gnu_parallel::parallelism);
+
+ template<typename _RAIter1, typename _RAIter2, typename _Tp,
+ typename BinaryFunction1, typename BinaryFunction2>
+ _Tp
+ inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1,
+ BinaryFunction2, random_access_iterator_tag,
+ random_access_iterator_tag,
+ __gnu_parallel::parallelism);
+
+ template<typename _IIter1, typename _IIter2, typename _Tp,
+ typename _BinaryFunction1, typename _BinaryFunction2,
+ typename _Tag1, typename _Tag2>
+ _Tp
+ inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1,
+ _BinaryFunction2, _Tag1, _Tag2);
template<typename _IIter, typename _OIter>
- inline _OIter
- partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
+ _OIter
+ partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- inline _OIter
- partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag);
+ _OIter
+ partial_sum(_IIter, _IIter, _OIter, _BinaryOper,
+ __gnu_parallel::sequential_tag);
template<typename _IIter, typename _OIter>
- inline _OIter
- partial_sum(_IIter, _IIter, _OIter result);
+ _OIter
+ partial_sum(_IIter, _IIter, _OIter result);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- inline _OIter
- partial_sum(_IIter, _IIter, _OIter, _BinaryOper);
+ _OIter
+ partial_sum(_IIter, _IIter, _OIter, _BinaryOper);
- template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2>
- inline _OIter
- partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
+ template<typename _IIter, typename _OIter, typename _BinaryOper,
+ typename _Tag1, typename _Tag2>
+ _OIter
+ partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2);
template<typename _IIter, typename _OIter, typename _BinaryOper>
- _OIter
- partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag);
+ _OIter
+ partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper,
+ random_access_iterator_tag, random_access_iterator_tag);
} // end namespace
} // end namespace
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* @return User-supplied functor (that may contain a part of the result).
*/
template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
+ typename Op,
+ typename Fu,
+ typename Red,
+ typename Result>
Op
- for_each_template_random_access_omp_loop(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r, Result base, Result& output,
- typename std::iterator_traits<RandomAccessIterator>::
- difference_type bound)
+ for_each_template_random_access_omp_loop(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Op o, Fu& f, Red r, Result base,
+ Result& output,
+ typename std::iterator_traits
+ <RandomAccessIterator>::
+ difference_type bound)
{
typedef typename
std::iterator_traits<RandomAccessIterator>::difference_type
difference_type length = end - begin;
thread_index_t num_threads =
- __gnu_parallel::min<difference_type>(get_max_threads(), length);
+ __gnu_parallel::min<difference_type>(get_max_threads(), length);
Result *thread_results;
num_threads = omp_get_num_threads();
thread_results = new Result[num_threads];
- for (thread_index_t i = 0; i < num_threads; i++)
+ for (thread_index_t i = 0; i < num_threads; ++i)
thread_results[i] = Result();
}
thread_index_t iam = omp_get_thread_num();
# pragma omp for schedule(dynamic, Settings::workstealing_chunk_size)
- for (difference_type pos = 0; pos < length; pos++)
+ for (difference_type pos = 0; pos < length; ++pos)
thread_results[iam] =
r(thread_results[iam], f(o, begin+pos));
} //parallel
- for (thread_index_t i = 0; i < num_threads; i++)
+ for (thread_index_t i = 0; i < num_threads; ++i)
output = r(output, thread_results[i]);
delete [] thread_results;
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* @return User-supplied functor (that may contain a part of the result).
*/
template<typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
+ typename Op,
+ typename Fu,
+ typename Red,
+ typename Result>
Op
- for_each_template_random_access_omp_loop_static(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r, Result base, Result& output,
- typename std::iterator_traits<RandomAccessIterator>::
- difference_type bound)
+ for_each_template_random_access_omp_loop_static(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Op o, Fu& f, Red r,
+ Result base, Result& output,
+ typename std::iterator_traits
+ <RandomAccessIterator>::
+ difference_type bound)
{
typedef typename
- std::iterator_traits<RandomAccessIterator>::difference_type
- difference_type;
+ std::iterator_traits<RandomAccessIterator>::difference_type
+ difference_type;
difference_type length = end - begin;
thread_index_t num_threads =
- std::min<difference_type>(get_max_threads(), length);
+ std::min<difference_type>(get_max_threads(), length);
Result *thread_results;
num_threads = omp_get_num_threads();
thread_results = new Result[num_threads];
- for (thread_index_t i = 0; i < num_threads; i++)
+ for (thread_index_t i = 0; i < num_threads; ++i)
thread_results[i] = Result();
}
thread_index_t iam = omp_get_thread_num();
# pragma omp for schedule(static, Settings::workstealing_chunk_size)
- for (difference_type pos = 0; pos < length; pos++)
- thread_results[iam] =
- r(thread_results[iam], f(o, begin+pos));
+ for (difference_type pos = 0; pos < length; ++pos)
+ thread_results[iam] = r(thread_results[iam], f(o, begin+pos));
} //parallel
- for (thread_index_t i = 0; i < num_threads; i++)
- output = r(output, thread_results[i]);
+ for (thread_index_t i = 0; i < num_threads; ++i)
+ output = r(output, thread_results[i]);
delete [] thread_results;
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<
- typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
+template<typename RandomAccessIterator,
+ typename Op,
+ typename Fu,
+ typename Red,
+ typename Result>
Op
- for_each_template_random_access_ed(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Op o, Fu& f, Red r, Result base, Result& output,
- typename std::iterator_traits<RandomAccessIterator>::
- difference_type bound)
+ for_each_template_random_access_ed(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Op o, Fu& f, Red r, Result base,
+ Result& output,
+ typename std::iterator_traits
+ <RandomAccessIterator>::
+ difference_type bound)
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::difference_type difference_type;
Result *thread_results;
thread_index_t num_threads =
- __gnu_parallel::min<difference_type>(get_max_threads(), length);
+ __gnu_parallel::min<difference_type>(get_max_threads(), length);
# pragma omp parallel num_threads(num_threads)
{
thread_results[iam] = reduct;
} //parallel
- for (thread_index_t i = 0; i < num_threads; i++)
+ for (thread_index_t i = 0; i < num_threads; ++i)
output = r(output, thread_results[i]);
// Points to last element processed (needed as return value for
* @param value Start value. Must be passed since the neutral
* element is unknown in general.
* @return End iterator of output sequence. */
-template<
- typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
- inline OutputIterator
- parallel_partial_sum_basecase(
- InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- typename std::iterator_traits<InputIterator>::value_type value)
+template<typename InputIterator,
+ typename OutputIterator,
+ typename BinaryOperation>
+ OutputIterator
+ parallel_partial_sum_basecase(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ typename std::iterator_traits
+ <InputIterator>::value_type value)
{
if (begin == end)
return result;
* @param num_threads Number of threads to use.
* @return End iterator of output sequence.
*/
-template<
- typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename BinaryOperation>
OutputIterator
- parallel_partial_sum_linear(
- InputIterator begin, InputIterator end,
- OutputIterator result, BinaryOperation bin_op,
- typename std::iterator_traits<InputIterator>::difference_type n)
+ parallel_partial_sum_linear(InputIterator begin, InputIterator end,
+ OutputIterator result, BinaryOperation bin_op,
+ typename std::iterator_traits
+ <InputIterator>::difference_type n)
{
typedef std::iterator_traits<InputIterator> traits_type;
typedef typename traits_type::value_type value_type;
else
{
difference_type chunk_length =
- ((double)n /
- ((double)num_threads + Settings::partial_sum_dilatation)),
- borderstart = n - num_threads * chunk_length;
+ ((double)n
+ / ((double)num_threads
+ + Settings::partial_sum_dilatation)),
+ borderstart = n - num_threads * chunk_length;
borders[0] = 0;
for (int i = 1; i < (num_threads + 1); ++i)
{
borders[num_threads + 1] = n;
}
- sums = static_cast<value_type*>(
- ::operator new(sizeof(value_type) * num_threads));
+ sums = static_cast<value_type*>(::operator new(sizeof(value_type)
+ * num_threads));
OutputIterator target_end;
} //single
{
*result = *begin;
parallel_partial_sum_basecase(begin + 1, begin + borders[1],
- result + 1, bin_op, *begin);
+ result + 1, bin_op, *begin);
::new(&(sums[iam])) value_type(*(result + borders[1] - 1));
}
else
{
- ::new(&(sums[iam])) value_type(
- std::accumulate(begin + borders[iam] + 1,
- begin + borders[iam + 1],
- *(begin + borders[iam]),
- bin_op, __gnu_parallel::sequential_tag()));
+ ::new(&(sums[iam]))
+ value_type(std::accumulate(begin + borders[iam] + 1,
+ begin + borders[iam + 1],
+ *(begin + borders[iam]),
+ bin_op,
+ __gnu_parallel::sequential_tag()));
}
# pragma omp barrier
// Still same team.
parallel_partial_sum_basecase(begin + borders[iam + 1],
- begin + borders[iam + 2],
- result + borders[iam + 1], bin_op,
- sums[iam]);
+ begin + borders[iam + 2],
+ result + borders[iam + 1], bin_op,
+ sums[iam]);
} //parallel
::operator delete(sums);
* @param result Begin iterator of output sequence.
* @param bin_op Associative binary function.
* @return End iterator of output sequence. */
-template<
- typename InputIterator,
- typename OutputIterator,
- typename BinaryOperation>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename BinaryOperation>
OutputIterator
parallel_partial_sum(InputIterator begin, InputIterator end,
OutputIterator result, BinaryOperation bin_op)
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
reserved_right = new bool[num_threads];
if (Settings::partition_chunk_share > 0.0)
- chunk_size = std::max<difference_type>(
- Settings::partition_chunk_size,
- (double)n * Settings::partition_chunk_share /
- (double)num_threads);
+ chunk_size = std::max<difference_type>(Settings::
+ partition_chunk_size,
+ (double)n * Settings::
+ partition_chunk_share
+ / (double)num_threads);
else
chunk_size = Settings::partition_chunk_size;
}
{
difference_type num_chunks = (right - left + 1) / chunk_size;
- for (int r = 0; r < num_threads; r++)
+ for (int r = 0; r < num_threads; ++r)
{
reserved_left[r] = false;
reserved_right[r] = false;
{
while (pred(begin[thread_left])
&& thread_left <= thread_left_border)
- thread_left++;
+ ++thread_left;
while (!pred(begin[thread_right])
&& thread_right >= thread_right_border)
- thread_right--;
+ --thread_right;
if (thread_left > thread_left_border
|| thread_right < thread_right_border)
break;
std::swap(begin[thread_left], begin[thread_right]);
- thread_left++;
- thread_right--;
+ ++thread_left;
+ --thread_right;
}
}
// Now swap the leftover chunks to the right places.
if (thread_left <= thread_left_border)
# pragma omp atomic
- leftover_left++;
+ ++leftover_left;
if (thread_right >= thread_right_border)
# pragma omp atomic
- leftover_right++;
+ ++leftover_right;
# pragma omp barrier
&& thread_right_border <= rightnew)
{
// Chunk already in place, reserve spot.
- reserved_right
- [((thread_right_border - 1) - right) / chunk_size]
- = true;
+ reserved_right[((thread_right_border - 1) - right)
+ / chunk_size] = true;
}
# pragma omp barrier
// Find spot and swap.
difference_type swapstart = -1;
omp_set_lock(&result_lock);
- for (int r = 0; r < leftover_left; r++)
+ for (int r = 0; r < leftover_left; ++r)
if (!reserved_left[r])
{
reserved_left[r] = true;
_GLIBCXX_PARALLEL_ASSERT(swapstart != -1);
#endif
- std::swap_ranges(
- begin + thread_left_border - (chunk_size - 1),
- begin + thread_left_border + 1,
- begin + swapstart);
+ std::swap_ranges(begin + thread_left_border
+ - (chunk_size - 1),
+ begin + thread_left_border + 1,
+ begin + swapstart);
}
if (thread_right >= thread_right_border
// Find spot and swap
difference_type swapstart = -1;
omp_set_lock(&result_lock);
- for (int r = 0; r < leftover_right; r++)
+ for (int r = 0; r < leftover_right; ++r)
if (!reserved_right[r])
{
reserved_right[r] = true;
#endif
std::swap_ranges(begin + thread_right_border,
- begin + thread_right_border + chunk_size,
- begin + swapstart);
+ begin + thread_right_border + chunk_size,
+ begin + swapstart);
}
#if _GLIBCXX_ASSERTIONS
# pragma omp barrier
# pragma omp single
{
- for (int r = 0; r < leftover_left; r++)
+ for (int r = 0; r < leftover_left; ++r)
_GLIBCXX_PARALLEL_ASSERT(reserved_left[r]);
- for (int r = 0; r < leftover_right; r++)
+ for (int r = 0; r < leftover_right; ++r)
_GLIBCXX_PARALLEL_ASSERT(reserved_right[r]);
}
{
// Go right until key is geq than pivot.
while (pred(begin[final_left]) && final_left < final_right)
- final_left++;
+ ++final_left;
// Go left until key is less than pivot.
while (!pred(begin[final_right]) && final_left < final_right)
- final_right--;
+ --final_right;
if (final_left == final_right)
break;
std::swap(begin[final_left], begin[final_right]);
- final_left++;
- final_right--;
+ ++final_left;
+ --final_right;
}
// All elements on the left side are < piv, all elements on the
RandomAccessIterator split;
random_number rng;
- difference_type minimum_length = std::max<difference_type>(2, Settings::partition_minimal_n);
+ difference_type minimum_length =
+ std::max<difference_type>(2, Settings::partition_minimal_n);
// Break if input range to small.
while (static_cast<sequence_index_t>(end - begin) >= minimum_length)
std::swap(*pivot_pos, *(end - 1));
pivot_pos = end - 1;
- // XXX Comparator must have first_value_type, second_value_type, result_type
- // Comparator == __gnu_parallel::lexicographic<S, int, __gnu_parallel::less<S, S> >
+ // XXX Comparator must have first_value_type, second_value_type,
+ // result_type
+ // Comparator == __gnu_parallel::lexicographic<S, int,
+ // __gnu_parallel::less<S, S> >
// pivot_pos == std::pair<S, int>*
// XXX binder2nd only for RandomAccessIterators??
- __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool> pred(comp, *pivot_pos);
+ __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
+ pred(comp, *pivot_pos);
// Divide, leave pivot unchanged in last place.
RandomAccessIterator split_pos1, split_pos2;
- split_pos1 = begin + parallel_partition(begin, end - 1, pred, get_max_threads());
+ split_pos1 = begin + parallel_partition(begin, end - 1, pred,
+ get_max_threads());
// Left side: < pivot_pos; right side: >= pivot_pos
pivot_pos = split_pos1;
// In case all elements are equal, split_pos1 == 0
- if ((split_pos1 + 1 - begin) < (n >> 7) || (end - split_pos1) < (n >> 7))
+ if ((split_pos1 + 1 - begin) < (n >> 7)
+ || (end - split_pos1) < (n >> 7))
{
// Very unequal split, one part smaller than one 128th
// elements not stricly larger than the pivot.
- __gnu_parallel::unary_negate<__gnu_parallel::binder1st<Comparator, value_type, value_type, bool>, value_type> pred(__gnu_parallel::binder1st<Comparator, value_type, value_type, bool>(comp, *pivot_pos));
+ __gnu_parallel::unary_negate<__gnu_parallel::
+ binder1st<Comparator, value_type, value_type, bool>, value_type>
+ pred(__gnu_parallel::binder1st<Comparator, value_type,
+ value_type, bool>(comp, *pivot_pos));
// Find other end of pivot-equal range.
- split_pos2 = __gnu_sequential::partition(split_pos1 + 1, end, pred);
+ split_pos2 = __gnu_sequential::partition(split_pos1 + 1,
+ end, pred);
}
else
// Only skip the pivot.
* @param comp Comparator. */
template<typename RandomAccessIterator, typename Comparator>
void
- parallel_partial_sort(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, Comparator comp)
+ parallel_partial_sort(RandomAccessIterator begin,
+ RandomAccessIterator middle,
+ RandomAccessIterator end, Comparator comp)
{
parallel_nth_element(begin, middle, end, comp);
std::sort(begin, middle, comp);
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* Calling them would not make sense in a concurrent setting.
* @param T Contained element type. */
template<typename T>
- class RestrictedBoundedConcurrentQueue
- {
- private:
- /** @brief Array of elements, seen as cyclic buffer. */
- T* base;
-
- /** @brief Maximal number of elements contained at the same time. */
- sequence_index_t max_size;
-
- /** @brief Cyclic begin and end pointers contained in one
- atomically changeable value. */
- _GLIBCXX_VOLATILE lcas_t borders;
-
- public:
- /** @brief Constructor. Not to be called concurrent, of course.
- * @param max_size Maximal number of elements to be contained. */
- RestrictedBoundedConcurrentQueue(sequence_index_t max_size)
+ class RestrictedBoundedConcurrentQueue
{
- this->max_size = max_size;
- base = new T[max_size];
- borders = encode2(0, 0);
+ private:
+ /** @brief Array of elements, seen as cyclic buffer. */
+ T* base;
+
+ /** @brief Maximal number of elements contained at the same time. */
+ sequence_index_t max_size;
+
+ /** @brief Cyclic begin and end pointers contained in one
+ atomically changeable value. */
+ _GLIBCXX_VOLATILE lcas_t borders;
+
+ public:
+ /** @brief Constructor. Not to be called concurrent, of course.
+ * @param max_size Maximal number of elements to be contained. */
+ RestrictedBoundedConcurrentQueue(sequence_index_t max_size)
+ {
+ this->max_size = max_size;
+ base = new T[max_size];
+ borders = encode2(0, 0);
#pragma omp flush
- }
-
- /** @brief Destructor. Not to be called concurrent, of course. */
- ~RestrictedBoundedConcurrentQueue()
- {
- delete[] base;
- }
-
- /** @brief Pushes one element into the queue at the front end.
- * Must not be called concurrently with pop_front(). */
- void push_front(const T& t)
- {
- lcas_t former_borders = borders;
- int former_front, former_back;
- decode2(former_borders, former_front, former_back);
- *(base + former_front % max_size) = t;
+ }
+
+ /** @brief Destructor. Not to be called concurrent, of course. */
+ ~RestrictedBoundedConcurrentQueue()
+ { delete[] base; }
+
+ /** @brief Pushes one element into the queue at the front end.
+ * Must not be called concurrently with pop_front(). */
+ void
+ push_front(const T& t)
+ {
+ lcas_t former_borders = borders;
+ int former_front, former_back;
+ decode2(former_borders, former_front, former_back);
+ *(base + former_front % max_size) = t;
#if _GLIBCXX_ASSERTIONS
- // Otherwise: front - back > max_size eventually.
- _GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back) <= max_size);
+ // Otherwise: front - back > max_size eventually.
+ _GLIBCXX_PARALLEL_ASSERT(((former_front + 1) - former_back)
+ <= max_size);
#endif
- fetch_and_add(&borders, encode2(1, 0));
- }
-
- /** @brief Pops one element from the queue at the front end.
- * Must not be called concurrently with pop_front(). */
- bool pop_front(T& t)
- {
- int former_front, former_back;
+ fetch_and_add(&borders, encode2(1, 0));
+ }
+
+ /** @brief Pops one element from the queue at the front end.
+ * Must not be called concurrently with pop_front(). */
+ bool
+ pop_front(T& t)
+ {
+ int former_front, former_back;
#pragma omp flush
- decode2(borders, former_front, former_back);
- while (former_front > former_back)
- {
- // Chance.
- lcas_t former_borders = encode2(former_front, former_back);
- lcas_t new_borders = encode2(former_front - 1, former_back);
- if (compare_and_swap(&borders, former_borders, new_borders))
- {
- t = *(base + (former_front - 1) % max_size);
- return true;
- }
+ decode2(borders, former_front, former_back);
+ while (former_front > former_back)
+ {
+ // Chance.
+ lcas_t former_borders = encode2(former_front, former_back);
+ lcas_t new_borders = encode2(former_front - 1, former_back);
+ if (compare_and_swap(&borders, former_borders, new_borders))
+ {
+ t = *(base + (former_front - 1) % max_size);
+ return true;
+ }
#pragma omp flush
- decode2(borders, former_front, former_back);
- }
- return false;
- }
-
- /** @brief Pops one element from the queue at the front end.
- * Must not be called concurrently with pop_front(). */
- bool pop_back(T& t) //queue behavior
- {
- int former_front, former_back;
+ decode2(borders, former_front, former_back);
+ }
+ return false;
+ }
+
+ /** @brief Pops one element from the queue at the front end.
+ * Must not be called concurrently with pop_front(). */
+ bool
+ pop_back(T& t) //queue behavior
+ {
+ int former_front, former_back;
#pragma omp flush
- decode2(borders, former_front, former_back);
- while (former_front > former_back)
- {
- // Chance.
- lcas_t former_borders = encode2(former_front, former_back);
- lcas_t new_borders = encode2(former_front, former_back + 1);
- if (compare_and_swap(&borders, former_borders, new_borders))
- {
- t = *(base + former_back % max_size);
- return true;
- }
+ decode2(borders, former_front, former_back);
+ while (former_front > former_back)
+ {
+ // Chance.
+ lcas_t former_borders = encode2(former_front, former_back);
+ lcas_t new_borders = encode2(former_front, former_back + 1);
+ if (compare_and_swap(&borders, former_borders, new_borders))
+ {
+ t = *(base + former_back % max_size);
+ return true;
+ }
#pragma omp flush
- decode2(borders, former_front, former_back);
- }
- return false;
- }
+ decode2(borders, former_front, former_back);
+ }
+ return false;
+ }
};
} //namespace __gnu_parallel
* this part.
*/
template<typename RandomAccessIterator, typename Comparator>
- inline
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- parallel_sort_qs_divide(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp,
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- pivot_rank,
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- num_samples,
- thread_index_t num_threads)
- {
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
-
- difference_type n = end - begin;
- num_samples = std::min(num_samples, n);
-
- // Allocate uninitialized, to avoid default constructor.
- value_type* samples = static_cast<value_type*>(
- ::operator new(num_samples * sizeof(value_type)));
-
- for (difference_type s = 0; s < num_samples; ++s)
- {
- const unsigned long long index = static_cast<unsigned long long>(s)
- * n / num_samples;
- ::new(&(samples[s])) value_type(begin[index]);
- }
+ typename std::iterator_traits<RandomAccessIterator>::difference_type
+ parallel_sort_qs_divide(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Comparator comp, typename std::iterator_traits
+ <RandomAccessIterator>::difference_type pivot_rank,
+ typename std::iterator_traits
+ <RandomAccessIterator>::difference_type
+ num_samples, thread_index_t num_threads)
+ {
+ typedef std::iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ difference_type n = end - begin;
+ num_samples = std::min(num_samples, n);
+
+ // Allocate uninitialized, to avoid default constructor.
+ value_type* samples =
+ static_cast<value_type*>(::operator new(num_samples
+ * sizeof(value_type)));
+
+ for (difference_type s = 0; s < num_samples; ++s)
+ {
+ const unsigned long long index = static_cast<unsigned long long>(s)
+ * n / num_samples;
+ ::new(&(samples[s])) value_type(begin[index]);
+ }
- __gnu_sequential::sort(samples, samples + num_samples, comp);
+ __gnu_sequential::sort(samples, samples + num_samples, comp);
- value_type& pivot = samples[pivot_rank * num_samples / n];
+ value_type& pivot = samples[pivot_rank * num_samples / n];
- __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
+ __gnu_parallel::binder2nd<Comparator, value_type, value_type, bool>
pred(comp, pivot);
- difference_type split = parallel_partition(begin, end, pred, num_threads);
+ difference_type split = parallel_partition(begin, end, pred, num_threads);
- ::operator delete(samples);
+ ::operator delete(samples);
- return split;
- }
+ return split;
+ }
/** @brief Unbalanced quicksort conquer step.
* @param begin Begin iterator of subsequence.
* this part.
*/
template<typename RandomAccessIterator, typename Comparator>
- inline void
- parallel_sort_qs_conquer(RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp,
- thread_index_t num_threads)
- {
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
-
- if (num_threads <= 1)
- {
- __gnu_sequential::sort(begin, end, comp);
- return;
- }
+ void
+ parallel_sort_qs_conquer(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Comparator comp,
+ thread_index_t num_threads)
+ {
+ typedef std::iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ if (num_threads <= 1)
+ {
+ __gnu_sequential::sort(begin, end, comp);
+ return;
+ }
- difference_type n = end - begin, pivot_rank;
+ difference_type n = end - begin, pivot_rank;
- if (n <= 1)
- return;
+ if (n <= 1)
+ return;
- thread_index_t num_threads_left;
+ thread_index_t num_threads_left;
- if ((num_threads % 2) == 1)
- num_threads_left = num_threads / 2 + 1;
- else
- num_threads_left = num_threads / 2;
+ if ((num_threads % 2) == 1)
+ num_threads_left = num_threads / 2 + 1;
+ else
+ num_threads_left = num_threads / 2;
- pivot_rank = n * num_threads_left / num_threads;
+ pivot_rank = n * num_threads_left / num_threads;
- difference_type split = parallel_sort_qs_divide(
- begin, end, comp, pivot_rank,
- Settings::sort_qs_num_samples_preset, num_threads);
+ difference_type split =
+ parallel_sort_qs_divide(begin, end, comp, pivot_rank,
+ Settings::sort_qs_num_samples_preset,
+ num_threads);
#pragma omp parallel sections
- {
+ {
#pragma omp section
- parallel_sort_qs_conquer(begin, begin + split,
- comp, num_threads_left);
+ parallel_sort_qs_conquer(begin, begin + split,
+ comp, num_threads_left);
#pragma omp section
- parallel_sort_qs_conquer(begin + split, end,
- comp, num_threads - num_threads_left);
+ parallel_sort_qs_conquer(begin + split, end,
+ comp, num_threads - num_threads_left);
+ }
}
- }
* this part.
*/
template<typename RandomAccessIterator, typename Comparator>
- inline void
- parallel_sort_qs(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Comparator comp,
- typename std::iterator_traits<RandomAccessIterator>::difference_type n,
- int num_threads)
- {
- _GLIBCXX_CALL(n)
-
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
-
- if (n == 0)
- return;
-
- // At least one element per processor.
- if (num_threads > n)
- num_threads = static_cast<thread_index_t>(n);
-
- Settings::sort_qs_num_samples_preset = 100;
-
- // Hard to avoid.
- omp_set_num_threads(num_threads);
-
- parallel_sort_qs_conquer(begin, begin + n, comp, num_threads);
- }
+ void
+ parallel_sort_qs(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Comparator comp, typename std::iterator_traits
+ <RandomAccessIterator>::difference_type n,
+ int num_threads)
+ {
+ _GLIBCXX_CALL(n)
+
+ typedef std::iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ if (n == 0)
+ return;
+
+ // At least one element per processor.
+ if (num_threads > n)
+ num_threads = static_cast<thread_index_t>(n);
+
+ Settings::sort_qs_num_samples_preset = 100;
+
+ // Hard to avoid.
+ omp_set_num_threads(num_threads);
+
+ parallel_sort_qs_conquer(begin, begin + n, comp, num_threads);
+ }
} //namespace __gnu_parallel
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// http://www.math.keio.ac.jp/matumoto/emt.html
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- class mersenne_twister
- {
- public:
- typedef UIntType result_type;
- static const int word_size = w;
- static const int state_size = n;
- static const int shift_size = m;
- static const int mask_bits = r;
- static const UIntType parameter_a = a;
- static const int output_u = u;
- static const int output_s = s;
- static const UIntType output_b = b;
- static const int output_t = t;
- static const UIntType output_c = c;
- static const int output_l = l;
-
- static const bool has_fixed_range = false;
-
- mersenne_twister() { seed(); }
+ class mersenne_twister
+ {
+ public:
+ typedef UIntType result_type;
+ static const int word_size = w;
+ static const int state_size = n;
+ static const int shift_size = m;
+ static const int mask_bits = r;
+ static const UIntType parameter_a = a;
+ static const int output_u = u;
+ static const int output_s = s;
+ static const UIntType output_b = b;
+ static const int output_t = t;
+ static const UIntType output_c = c;
+ static const int output_l = l;
+
+ static const bool has_fixed_range = false;
+
+ mersenne_twister() { seed(); }
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
- // Work around overload resolution problem (Gennadiy E. Rozental)
- explicit mersenne_twister(const UIntType& value)
+ // Work around overload resolution problem (Gennadiy E. Rozental)
+ explicit
+ mersenne_twister(const UIntType& value)
#else
- explicit mersenne_twister(UIntType value)
+ explicit
+ mersenne_twister(UIntType value)
#endif
- { seed(value); }
- template<typename It> mersenne_twister(It& first, It last) { seed(first,last); }
+ { seed(value); }
- template<typename Generator>
- explicit mersenne_twister(Generator & gen) { seed(gen); }
+ template<typename It>
+ mersenne_twister(It& first, It last)
+ { seed(first,last); }
- // compiler-generated copy ctor and assignment operator are fine
+ template<typename Generator>
+ explicit
+ mersenne_twister(Generator & gen)
+ { seed(gen); }
- void seed() { seed(UIntType(5489)); }
+ // compiler-generated copy ctor and assignment operator are fine
+
+ void
+ seed()
+ { seed(UIntType(5489)); }
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
- // Work around overload resolution problem (Gennadiy E. Rozental)
- void seed(const UIntType& value)
+ // Work around overload resolution problem (Gennadiy E. Rozental)
+ void
+ seed(const UIntType& value)
#else
- void seed(UIntType value)
+ void
+ seed(UIntType value)
#endif
- {
- // New seeding algorithm from
+ {
+ // New seeding algorithm from
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
- // In the previous versions, MSBs of the seed affected only MSBs of the
- // state x[].
- const UIntType mask = ~0u;
- x[0] = value & mask;
- for (i = 1; i < n; i++) {
- // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
- x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
+ // In the previous versions, MSBs of the seed affected only MSBs of the
+ // state x[].
+ const UIntType mask = ~0u;
+ x[0] = value & mask;
+ for (i = 1; i < n; ++i)
+ {
+ // See Knuth "The Art of Computer Programming" Vol. 2,
+ // 3rd ed., page 106
+ x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
+ }
}
- }
- // For GCC, moving this function out-of-line prevents inlining, which may
- // reduce overall object code size. However, MSVC does not grok
- // out-of-line definitions of member function templates.
- template<typename Generator>
- void seed(Generator & gen)
- {
- // I could have used std::generate_n, but it takes "gen" by value
- for (int j = 0; j < n; j++)
- x[j] = gen();
- i = n;
- }
+ // For GCC, moving this function out-of-line prevents inlining, which may
+ // reduce overall object code size. However, MSVC does not grok
+ // out-of-line definitions of member function templates.
+ template<typename Generator>
+ void
+ seed(Generator & gen)
+ {
+ // I could have used std::generate_n, but it takes "gen" by value
+ for (int j = 0; j < n; ++j)
+ x[j] = gen();
+ i = n;
+ }
- template<typename It>
- void seed(It& first, It last)
- {
- int j;
- for (j = 0; j < n && first != last; ++j, ++first)
- x[j] = *first;
- i = n;
- /* if (first == last && j < n)
- throw std::invalid_argument("mersenne_twister::seed");*/
- }
+ template<typename It>
+ void
+ seed(It& first, It last)
+ {
+ int j;
+ for (j = 0; j < n && first != last; ++j, ++first)
+ x[j] = *first;
+ i = n;
+ /* if (first == last && j < n)
+ throw std::invalid_argument("mersenne_twister::seed");*/
+ }
- result_type min() const { return 0; }
- result_type max() const
- {
- // avoid "left shift count >= with of type" warning
- result_type res = 0;
- for (int i = 0; i < w; ++i)
- res |= (1u << i);
- return res;
- }
+ result_type
+ min() const
+ { return 0; }
+
+ result_type
+ max() const
+ {
+ // avoid "left shift count >= with of type" warning
+ result_type res = 0;
+ for (int i = 0; i < w; ++i)
+ res |= (1u << i);
+ return res;
+ }
- result_type operator()();
- static bool validation(result_type v) { return val == v; }
+ result_type
+ operator()();
+
+ static bool
+ validation(result_type v)
+ { return val == v; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
- friend bool operator==(const mersenne_twister& x, const mersenne_twister& y)
- {
- for (int j = 0; j < state_size; ++j)
- if (x.compute(j) != y.compute(j))
- return false;
- return true;
- }
+ friend bool
+ operator==(const mersenne_twister& x, const mersenne_twister& y)
+ {
+ for (int j = 0; j < state_size; ++j)
+ if (x.compute(j) != y.compute(j))
+ return false;
+ return true;
+ }
- friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y)
- { return !(x == y); }
+ friend bool
+ operator!=(const mersenne_twister& x, const mersenne_twister& y)
+ { return !(x == y); }
#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const mersenne_twister& rhs) const
- {
- for (int j = 0; j < state_size; ++j)
- if (compute(j) != rhs.compute(j))
- return false;
- return true;
- }
+ // Use a member function; Streamable concept not supported.
+ bool
+ operator==(const mersenne_twister& rhs) const
+ {
+ for (int j = 0; j < state_size; ++j)
+ if (compute(j) != rhs.compute(j))
+ return false;
+ return true;
+ }
- bool operator!=(const mersenne_twister& rhs) const
- { return !(*this == rhs); }
+ bool
+ operator!=(const mersenne_twister& rhs) const
+ { return !(*this == rhs); }
#endif
- private:
- // returns x(i-n+index), where index is in 0..n-1
- UIntType compute(unsigned int index) const
- {
- // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
- return x[ (i + n + index) % (2*n) ];
- }
- void twist(int block);
+ private:
+ // returns x(i-n+index), where index is in 0..n-1
+ UIntType
+ compute(unsigned int index) const
+ {
+ // equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
+ return x[ (i + n + index) % (2*n) ];
+ }
+
+ void
+ twist(int block);
- // state representation: next output is o(x(i))
- // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
- // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
- // The goal is to always have x(i-n) ... x(i-1) available for
- // operator== and save/restore.
+ // state representation: next output is o(x(i))
+ // x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
+ // x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
+ // The goal is to always have x(i-n) ... x(i-1) available for
+ // operator== and save/restore.
- UIntType x[2*n];
- int i;
+ UIntType x[2*n];
+ int i;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const bool mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
+ const bool
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
+ const UIntType
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
+ const UIntType
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
+ const UIntType
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
+
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
+ const int
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
#endif
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- void mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
+ void
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
{
const UIntType upper_mask = (~0u) << r;
const UIntType lower_mask = ~upper_mask;
- if (block == 0) {
- for (int j = n; j < 2*n; j++) {
- UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
- x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
+ if (block == 0)
+ {
+ for (int j = n; j < 2*n; ++j)
+ {
+ UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
+ x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
+ }
}
- } else if (block == 1) {
- // split loop to avoid costly modulo operations
- { // extra scope for MSVC brokenness w.r.t. for scope
- for (int j = 0; j < n-m; j++) {
- UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
- x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
+ else if (block == 1)
+ {
+ // split loop to avoid costly modulo operations
+ { // extra scope for MSVC brokenness w.r.t. for scope
+ for (int j = 0; j < n-m; ++j)
+ {
+ UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
+ x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
+ }
}
+
+ for (int j = n-m; j < n-1; ++j)
+ {
+ UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
+ x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
+ }
+ // last iteration
+ UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
+ x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
+ i = 0;
}
-
- for (int j = n-m; j < n-1; j++) {
- UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
- x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
- }
- // last iteration
- UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
- x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
- i = 0;
- }
}
template<typename UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
- inline typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
- mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
- {
- if (i == n)
- twist(0);
- else if (i >= 2*n)
- twist(1);
- // Step 4
- UIntType z = x[i];
- ++i;
- z ^= (z >> u);
- z ^= ((z << s) & b);
- z ^= ((z << t) & c);
- z ^= (z >> l);
- return z;
- }
+ inline
+ typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
+ mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
+ {
+ if (i == n)
+ twist(0);
+ else if (i >= 2*n)
+ twist(1);
+ // Step 4
+ UIntType z = x[i];
+ ++i;
+ z ^= (z >> u);
+ z ^= ((z << s) & b);
+ z ^= ((z << t) & c);
+ z ^= (z >> l);
+ return z;
+ }
typedef mersenne_twister<uint32,32,351,175,19,0xccab8ee7,11,
uint64 supremum, RAND_SUP;
double supremum_reciprocal, RAND_SUP_REC;
- uint64 cache; /* assumed to be twice as long as the usual random number */
- int bits_left; /* bit results */
+ uint64 cache; /* assumed to be twice as long as the usual random number */
+ int bits_left; /* bit results */
- static inline uint32 scale_down(uint64 x,
+ static uint32
+ scale_down(uint64 x,
#if _GLIBCXX_SCALE_DOWN_FPU
- uint64 /*supremum*/, double supremum_reciprocal)
+ uint64 /*supremum*/, double supremum_reciprocal)
#else
- uint64 supremum, double /*supremum_reciprocal*/)
+ uint64 supremum, double /*supremum_reciprocal*/)
#endif
{
#if _GLIBCXX_SCALE_DOWN_FPU
#endif
}
-public:
- /** @brief Default constructor. Seed with 0. */
- random_number() :
- mt(0),
- supremum(0x100000000ULL),
- RAND_SUP(1ULL << (sizeof(uint32) * 8)),
- supremum_reciprocal((double)supremum / (double)RAND_SUP),
- RAND_SUP_REC(1.0 / (double)RAND_SUP),
- cache(0), bits_left(0)
- {
- }
-
- /** @brief Constructor.
- * @param seed Random seed.
- * @param supremum Generate integer random numbers in the interval @c [0,supremum). */
- random_number(uint32 seed, uint64 supremum = 0x100000000ULL) :
- mt(seed),
- supremum(supremum),
- RAND_SUP(1ULL << (sizeof(uint32) * 8)),
- supremum_reciprocal((double)supremum / (double)RAND_SUP),
- RAND_SUP_REC(1.0 / (double)RAND_SUP),
- cache(0), bits_left(0)
- {
- }
-
- /** @brief Generate unsigned random 32-bit integer. */
- inline uint32 operator()()
- {
- return scale_down(mt(), supremum, supremum_reciprocal);
- }
-
- /** @brief Generate unsigned random 32-bit integer in the interval @c [0,local_supremum). */
- inline uint32 operator()(uint64 local_supremum)
- {
- return scale_down(mt(), local_supremum, (double)local_supremum * RAND_SUP_REC);
- }
-
- /** @brief Set the random seed.
- * @param seed to set. */
- inline void set_seed(uint32 seed)
- {
- mt.seed(seed);
- cache = mt();
- bits_left = 32;
- }
+ public:
+ /** @brief Default constructor. Seed with 0. */
+ random_number()
+ : mt(0), supremum(0x100000000ULL),
+ RAND_SUP(1ULL << (sizeof(uint32) * 8)),
+ supremum_reciprocal((double)supremum / (double)RAND_SUP),
+ RAND_SUP_REC(1.0 / (double)RAND_SUP),
+ cache(0), bits_left(0) { }
+
+ /** @brief Constructor.
+ * @param seed Random seed.
+ * @param supremum Generate integer random numbers in the
+ * interval @c [0,supremum). */
+ random_number(uint32 seed, uint64 supremum = 0x100000000ULL)
+ : mt(seed), supremum(supremum),
+ RAND_SUP(1ULL << (sizeof(uint32) * 8)),
+ supremum_reciprocal((double)supremum / (double)RAND_SUP),
+ RAND_SUP_REC(1.0 / (double)RAND_SUP),
+ cache(0), bits_left(0) { }
+
+ /** @brief Generate unsigned random 32-bit integer. */
+ uint32
+ operator()()
+ { return scale_down(mt(), supremum, supremum_reciprocal); }
+
+ /** @brief Generate unsigned random 32-bit integer in the
+ interval @c [0,local_supremum). */
+ uint32
+ operator()(uint64 local_supremum)
+ {
+ return scale_down(mt(), local_supremum,
+ (double)local_supremum * RAND_SUP_REC);
+ }
- /** @brief Generate a number of random bits, compile-time parameter. */
- template<int bits>
- inline unsigned long genrand_bits()
- {
- unsigned long res = cache & ((1 << bits) - 1);
- cache = cache >> bits;
- bits_left -= bits;
- if (bits_left < 32)
- {
- cache |= (((uint64)mt()) << bits_left);
- bits_left += 32;
- }
- return res;
- }
+ /** @brief Set the random seed.
+ * @param seed to set. */
+ void
+ set_seed(uint32 seed)
+ {
+ mt.seed(seed);
+ cache = mt();
+ bits_left = 32;
+ }
- /** @brief Generate a number of random bits, run-time parameter.
- * @param bits Number of bits to generate. */
- inline unsigned long genrand_bits(int bits)
- {
- unsigned long res = cache & ((1 << bits) - 1);
- cache = cache >> bits;
- bits_left -= bits;
- if (bits_left < 32)
+ /** @brief Generate a number of random bits, compile-time parameter. */
+ template<int bits>
+ unsigned long
+ genrand_bits()
{
- cache |= (((uint64)mt()) << bits_left);
- bits_left += 32;
+ unsigned long res = cache & ((1 << bits) - 1);
+ cache = cache >> bits;
+ bits_left -= bits;
+ if (bits_left < 32)
+ {
+ cache |= (((uint64)mt()) << bits_left);
+ bits_left += 32;
+ }
+ return res;
}
- return res;
- }
+ /** @brief Generate a number of random bits, run-time parameter.
+ * @param bits Number of bits to generate. */
+ unsigned long
+ genrand_bits(int bits)
+ {
+ unsigned long res = cache & ((1 << bits) - 1);
+ cache = cache >> bits;
+ bits_left -= bits;
+ if (bits_left < 32)
+ {
+ cache |= (((uint64)mt()) << bits_left);
+ bits_left += 32;
+ }
+ return res;
+ }
};
} // namespace __gnu_parallel
/** @brief Random shuffle code executed by each thread.
* @param pus Array of thread-local data records. */
template<typename RandomAccessIterator, typename RandomNumberGenerator>
- inline void
+ void
parallel_random_shuffle_drs_pu(DRSSorterPU<RandomAccessIterator,
RandomNumberGenerator>* pus)
{
thread_index_t target_p = bin_proc[target_bin];
// Last column [d->num_threads] stays unchanged.
- ::new(&(temporaries[target_p][dist[target_bin + 1]++])) value_type(
- *(source + i + start));
+ ::new(&(temporaries[target_p][dist[target_bin + 1]++]))
+ value_type(*(source + i + start));
}
delete[] oracles;
* @param rng Random number generator to use.
*/
template<typename RandomAccessIterator, typename RandomNumberGenerator>
- inline void
- parallel_random_shuffle_drs(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- typename std::iterator_traits<RandomAccessIterator>::difference_type n,
- thread_index_t num_threads,
- RandomNumberGenerator& rng)
+ void
+ parallel_random_shuffle_drs(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ typename std::iterator_traits
+ <RandomAccessIterator>::difference_type n,
+ thread_index_t num_threads,
+ RandomNumberGenerator& rng)
{
typedef std::iterator_traits<RandomAccessIterator> traits_type;
typedef typename traits_type::value_type value_type;
* @param rng Random number generator to use.
*/
template<typename RandomAccessIterator, typename RandomNumberGenerator>
- inline void
+ void
sequential_random_shuffle(RandomAccessIterator begin,
RandomAccessIterator end,
RandomNumberGenerator& rng)
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* @param end2 End iterator of second sequence.
* @param pred Find predicate.
* @return Place of finding in first sequences. */
-template<
- typename _RandomAccessIterator1,
- typename _RandomAccessIterator2,
- typename Pred>
+template<typename _RandomAccessIterator1,
+ typename _RandomAccessIterator2,
+ typename Pred>
_RandomAccessIterator1
search_template(_RandomAccessIterator1 begin1, _RandomAccessIterator1 end1,
_RandomAccessIterator2 begin2, _RandomAccessIterator2 end2,
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
namespace __gnu_parallel
{
template<typename InputIterator, typename OutputIterator>
- inline OutputIterator
+ OutputIterator
copy_tail(std::pair<InputIterator, InputIterator> b,
std::pair<InputIterator, InputIterator> e, OutputIterator r)
{
return r;
}
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
struct symmetric_difference_func
{
typedef std::iterator_traits<InputIterator> traits_type;
Comparator comp;
- inline OutputIterator invoke(InputIterator a, InputIterator b,
- InputIterator c, InputIterator d,
- OutputIterator r) const
+ OutputIterator
+ invoke(InputIterator a, InputIterator b,
+ InputIterator c, InputIterator d,
+ OutputIterator r) const
{
while (a != b && c != d)
{
return std::copy(c, d, std::copy(a, b, r));
}
- inline difference_type
- count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
- const
+ difference_type
+ count(InputIterator a, InputIterator b,
+ InputIterator c, InputIterator d) const
{
difference_type counter = 0;
return counter + (b - a) + (d - c);
}
- inline OutputIterator
+ OutputIterator
first_empty(InputIterator c, InputIterator d, OutputIterator out) const
{ return std::copy(c, d, out); }
- inline OutputIterator
+ OutputIterator
second_empty(InputIterator a, InputIterator b, OutputIterator out) const
{ return std::copy(a, b, out); }
-
};
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
struct difference_func
{
typedef std::iterator_traits<InputIterator> traits_type;
Comparator comp;
- inline OutputIterator
+ OutputIterator
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
OutputIterator r) const
{
return std::copy(a, b, r);
}
- inline difference_type
- count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
- const
+ difference_type
+ count(InputIterator a, InputIterator b,
+ InputIterator c, InputIterator d) const
{
difference_type counter = 0;
};
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
struct intersection_func
{
typedef std::iterator_traits<InputIterator> traits_type;
Comparator comp;
- inline OutputIterator
+ OutputIterator
invoke(InputIterator a, InputIterator b, InputIterator c, InputIterator d,
OutputIterator r) const
{
return r;
}
- inline difference_type
- count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
- const
+ difference_type
+ count(InputIterator a, InputIterator b,
+ InputIterator c, InputIterator d) const
{
difference_type counter = 0;
struct union_func
{
typedef typename std::iterator_traits<InputIterator>::difference_type
- difference_type;
+ difference_type;
union_func(Comparator c) : comp(c) {}
Comparator comp;
- inline OutputIterator
+ OutputIterator
invoke(InputIterator a, const InputIterator b, InputIterator c,
const InputIterator d, OutputIterator r) const
{
return std::copy(c, d, std::copy(a, b, r));
}
- inline difference_type
- count(InputIterator a, InputIterator b, InputIterator c, InputIterator d)
- const
+ difference_type
+ count(InputIterator a, InputIterator b,
+ InputIterator c, InputIterator d) const
{
difference_type counter = 0;
{ return std::copy(a, b, out); }
};
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Operation>
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Operation>
OutputIterator
parallel_set_operation(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
}
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- OutputIterator
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
+ inline OutputIterator
parallel_set_union(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
OutputIterator result, Comparator comp)
union_func< InputIterator, OutputIterator, Comparator>(comp));
}
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- OutputIterator
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
+ inline OutputIterator
parallel_set_intersection(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
OutputIterator result, Comparator comp)
template<typename InputIterator, typename OutputIterator>
- OutputIterator
+ inline OutputIterator
set_intersection(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
OutputIterator result)
typedef typename traits_type::value_type value_type;
return set_intersection(begin1, end1, begin2, end2, result,
- std::less<value_type>());
+ std::less<value_type>());
}
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- OutputIterator
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
+ inline OutputIterator
parallel_set_difference(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
OutputIterator result, Comparator comp)
difference_func<InputIterator, OutputIterator, Comparator>(comp));
}
-template<
- typename InputIterator,
- typename OutputIterator,
- typename Comparator>
- OutputIterator
+template<typename InputIterator,
+ typename OutputIterator,
+ typename Comparator>
+ inline OutputIterator
parallel_set_symmetric_difference(InputIterator begin1, InputIterator end1,
InputIterator begin2, InputIterator end2,
OutputIterator result, Comparator comp)
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* whether to use parallelized algorithms.
* This file is a GNU parallel extension to the Standard C++ Library.
*
- * @section parallelization_decision The decision whether to run an algorithm in parallel.
+ * @section parallelization_decision The decision whether to run
+ * an algorithm in parallel.
*
* There are several ways the user can switch on and off the
* parallel execution of an algorithm, both at compile- and
* __gnu_parallel::Settings::force_parallel, i. e. usually a decision based on
* the input size.
*/
-#define _GLIBCXX_PARALLEL_CONDITION(c) (!(__gnu_parallel::Settings::force_sequential) && ((__gnu_parallel::get_max_threads() > 1 && (c)) || __gnu_parallel::Settings::force_parallel))
+#define _GLIBCXX_PARALLEL_CONDITION(c) \
+(!(__gnu_parallel::Settings::force_sequential) \
+ && ((__gnu_parallel::get_max_threads() > 1 \
+ && (c)) || __gnu_parallel::Settings::force_parallel))
namespace __gnu_parallel
{
/** @brief Different merging algorithms: bubblesort-alike,
loser-tree variants, enum sentinel */
enum MultiwayMergeAlgorithm
- { BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED, LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST };
+ { BUBBLE, LOSER_TREE_EXPLICIT, LOSER_TREE, LOSER_TREE_COMBINED,
+ LOSER_TREE_SENTINEL, MWM_ALGORITHM_LAST };
/** @brief Different splitting strategies for sorting/merging:
by sampling, exact */
volatile sequence_index_t Settings::partition_chunk_size = 1000;
volatile double Settings::partition_chunk_share = 0.0;
volatile unsigned int Settings::adjacent_difference_minimal_n = 1000;
- volatile Settings::PartialSumAlgorithm Settings::partial_sum_algorithm = Settings::LINEAR;
+ volatile Settings::PartialSumAlgorithm Settings::
+ partial_sum_algorithm = Settings::LINEAR;
volatile unsigned int Settings::partial_sum_minimal_n = 1000;
volatile float Settings::partial_sum_dilatation = 1.0f;
volatile unsigned int Settings::random_shuffle_minimal_n = 1000;
// unique copy
volatile sequence_index_t Settings::unique_copy_minimal_n = 10000;
- volatile Settings::MultiwayMergeAlgorithm Settings::multiway_merge_algorithm = Settings::LOSER_TREE;
- volatile Settings::Splitting Settings::multiway_merge_splitting = Settings::EXACT;
+ volatile Settings::MultiwayMergeAlgorithm Settings::
+ multiway_merge_algorithm = Settings::LOSER_TREE;
+ volatile Settings::Splitting Settings::multiway_merge_splitting =
+ Settings::EXACT;
volatile unsigned int Settings::multiway_merge_oversampling = 10;
- volatile Settings::FindDistribution Settings::find_distribution = Settings::CONSTANT_SIZE_BLOCKS;
+ volatile Settings::FindDistribution Settings::find_distribution =
+ Settings::CONSTANT_SIZE_BLOCKS;
volatile sequence_index_t Settings::find_sequential_search_size = 256;
volatile sequence_index_t Settings::find_initial_block_size = 256;
volatile sequence_index_t Settings::find_maximum_block_size = 8192;
volatile sequence_index_t Settings::set_union_minimal_n = 1000;
volatile sequence_index_t Settings::set_intersection_minimal_n = 1000;
volatile sequence_index_t Settings::set_difference_minimal_n = 1000;
- volatile sequence_index_t Settings::set_symmetric_difference_minimal_n = 1000;
+ volatile sequence_index_t Settings::set_symmetric_difference_minimal_n =
+ 1000;
volatile unsigned long long Settings::L1_cache_size = 16 << 10;
volatile unsigned long long Settings::L2_cache_size = 256 << 10;
volatile unsigned int Settings::TLB_size = 128;
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* @callgraph
*/
template<typename RandomAccessIterator, typename Comparator>
- inline void
- parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
- Comparator comp, bool stable)
- {
- _GLIBCXX_CALL(end - begin)
- typedef std::iterator_traits<RandomAccessIterator> traits_type;
- typedef typename traits_type::value_type value_type;
- typedef typename traits_type::difference_type difference_type;
-
- if (begin != end)
- {
- difference_type n = end - begin;
-
- if (false) ;
+ inline void
+ parallel_sort(RandomAccessIterator begin, RandomAccessIterator end,
+ Comparator comp, bool stable)
+ {
+ _GLIBCXX_CALL(end - begin)
+ typedef std::iterator_traits<RandomAccessIterator> traits_type;
+ typedef typename traits_type::value_type value_type;
+ typedef typename traits_type::difference_type difference_type;
+
+ if (begin != end)
+ {
+ difference_type n = end - begin;
+
+ if (false) ;
#if _GLIBCXX_MERGESORT
- else if (Settings::sort_algorithm == Settings::MWMS || stable)
- parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable);
+ else if (Settings::sort_algorithm == Settings::MWMS || stable)
+ parallel_sort_mwms(begin, end, comp, n, get_max_threads(), stable);
#endif
#if _GLIBCXX_QUICKSORT
- else if (Settings::sort_algorithm == Settings::QS && !stable)
- parallel_sort_qs(begin, end, comp, n, get_max_threads());
+ else if (Settings::sort_algorithm == Settings::QS && !stable)
+ parallel_sort_qs(begin, end, comp, n, get_max_threads());
#endif
#if _GLIBCXX_BAL_QUICKSORT
- else if (Settings::sort_algorithm == Settings::QS_BALANCED && !stable)
- parallel_sort_qsb(begin, end, comp, n, get_max_threads());
+ else if (Settings::sort_algorithm == Settings::QS_BALANCED
+ && !stable)
+ parallel_sort_qsb(begin, end, comp, n, get_max_threads());
#endif
- else
- __gnu_sequential::sort(begin, end, comp);
- }
- }
+ else
+ __gnu_sequential::sort(begin, end, comp);
+ }
+ }
} // end namespace __gnu_parallel
#endif
component, if present. Set kind component.
* @param T Simple type, nothing to unconst */
template<typename T>
- struct unconst_first_component
- {
- /** @brief New type after removing the const */
- typedef T type;
- };
+ struct unconst_first_component
+ {
+ /** @brief New type after removing the const */
+ typedef T type;
+ };
/** @brief Helper class: remove the const modifier from the first
component, if present. Map kind component
* @param Load Second component
* @sa unconst_first_component */
template<typename Key, typename Load>
- struct unconst_first_component<std::pair<const Key, Load> >
- {
- /** @brief New type after removing the const */
- typedef std::pair<Key, Load> type;
- };
+ struct unconst_first_component<std::pair<const Key, Load> >
+ {
+ /** @brief New type after removing the const */
+ typedef std::pair<Key, Load> type;
+ };
/** @brief Helper class: set the appropriate comparator to deal with
* repetitions. Comparator for unique dictionaries.
* @param _Key Keys to compare
* @param _Compare Comparator equal to conceptual < */
template<typename _Key, typename _Compare>
- struct StrictlyLess : public std::binary_function<_Key, _Key, bool>
- {
- /** @brief Comparator equal to conceptual < */
- _Compare c;
+ struct StrictlyLess : public std::binary_function<_Key, _Key, bool>
+ {
+ /** @brief Comparator equal to conceptual < */
+ _Compare c;
- /** @brief Constructor given a Comparator */
- StrictlyLess(const _Compare& _c) : c(_c) { }
+ /** @brief Constructor given a Comparator */
+ StrictlyLess(const _Compare& _c) : c(_c) { }
- /** @brief Copy constructor */
- StrictlyLess(const StrictlyLess<_Key, _Compare>& strictly_less)
- : c(strictly_less.c) { }
+ /** @brief Copy constructor */
+ StrictlyLess(const StrictlyLess<_Key, _Compare>& strictly_less)
+ : c(strictly_less.c) { }
- /** @brief Operator() */
- bool operator()(const _Key& k1, const _Key& k2) const
- {
- return c(k1, k2);
- }
- };
+ /** @brief Operator() */
+ bool
+ operator()(const _Key& k1, const _Key& k2) const
+ { return c(k1, k2); }
+ };
/** @brief Helper class: set the appropriate comparator to deal with
* repetitions. Comparator for non-unique dictionaries.
* @param _Key Keys to compare
* @param _Compare Comparator equal to conceptual <= */
template<typename _Key, typename _Compare>
- struct LessEqual : public std::binary_function<_Key, _Key, bool>
- {
- /** @brief Comparator equal to conceptual < */
- _Compare c;
+ struct LessEqual : public std::binary_function<_Key, _Key, bool>
+ {
+ /** @brief Comparator equal to conceptual < */
+ _Compare c;
- /** @brief Constructor given a Comparator */
- LessEqual(const _Compare& _c) : c(_c) { }
+ /** @brief Constructor given a Comparator */
+ LessEqual(const _Compare& _c) : c(_c) { }
- /** @brief Copy constructor */
- LessEqual(const LessEqual<_Key, _Compare>& less_equal)
- : c(less_equal.c) { }
+ /** @brief Copy constructor */
+ LessEqual(const LessEqual<_Key, _Compare>& less_equal)
+ : c(less_equal.c) { }
- /** @brief Operator() */
- bool operator()(const _Key& k1, const _Key& k2) const
- { return !c(k2, k1); }
- };
+ /** @brief Operator() */
+ bool
+ operator()(const _Key& k1, const _Key& k2) const
+ { return !c(k2, k1); }
+ };
/** @brief Parallel red-black tree.
* @param __last Last element of the input
*/
template<typename _InputIterator>
- void
- _M_insert_unique(_InputIterator __first, _InputIterator __last)
- {
- if (__first==__last) return;
- if (_GLIBCXX_PARALLEL_CONDITION(true))
- if (base_type::_M_impl._M_node_count == 0)
- {
- _M_bulk_insertion_construction(__first, __last, true,
- strictly_less);
- _GLIBCXX_PARALLEL_ASSERT(rb_verify());
- }
+ void
+ _M_insert_unique(_InputIterator __first, _InputIterator __last)
+ {
+ if (__first == __last)
+ return;
+
+ if (_GLIBCXX_PARALLEL_CONDITION(true))
+ if (base_type::_M_impl._M_node_count == 0)
+ {
+ _M_bulk_insertion_construction(__first, __last, true,
+ strictly_less);
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify());
+ }
+ else
+ {
+ _M_bulk_insertion_construction(__first, __last, false,
+ strictly_less);
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify());
+ }
else
- {
- _M_bulk_insertion_construction(__first, __last, false,
- strictly_less);
- _GLIBCXX_PARALLEL_ASSERT(rb_verify());
- }
- else
- {
base_type::_M_insert_unique(__first, __last);
- }
- }
+ }
/** @brief Parallel replacement of the sequential
* std::_Rb_tree::_M_insert_equal()
* @param __first First element of the input
* @param __last Last element of the input */
template<typename _InputIterator>
- void
- _M_insert_equal(_InputIterator __first, _InputIterator __last)
- {
- if (__first==__last) return;
- if (_GLIBCXX_PARALLEL_CONDITION(true))
- if (base_type::_M_impl._M_node_count == 0)
- _M_bulk_insertion_construction(__first, __last, true, less_equal);
+ void
+ _M_insert_equal(_InputIterator __first, _InputIterator __last)
+ {
+ if (__first == __last)
+ return;
+
+ if (_GLIBCXX_PARALLEL_CONDITION(true))
+ if (base_type::_M_impl._M_node_count == 0)
+ _M_bulk_insertion_construction(__first, __last, true, less_equal);
+ else
+ _M_bulk_insertion_construction(__first, __last, false, less_equal);
else
- _M_bulk_insertion_construction(__first, __last, false, less_equal);
- else
- base_type::_M_insert_equal(__first, __last);
- _GLIBCXX_PARALLEL_ASSERT(rb_verify());
- }
+ base_type::_M_insert_equal(__first, __last);
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify());
+ }
private:
* @param ranker Calculates the position of a node in an array of nodes
*/
template<typename ranker>
- class nodes_initializer
- {
- /** @brief Renaming of tree size_type */
+ class nodes_initializer
+ {
+ /** @brief Renaming of tree size_type */
- typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
- typedef typename tree_type::size_type size_type;
- public:
+ typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> tree_type;
+ typedef typename tree_type::size_type size_type;
+ public:
- /** @brief mask[%i]= 0..01..1, where the number of 1s is %i+1 */
- size_type mask[sizeof(size_type)*8];
+ /** @brief mask[%i]= 0..01..1, where the number of 1s is %i+1 */
+ size_type mask[sizeof(size_type)*8];
- /** @brief Array of nodes (initial address) */
- const _Rb_tree_node_ptr* r_init;
+ /** @brief Array of nodes (initial address) */
+ const _Rb_tree_node_ptr* r_init;
- /** @brief Total number of (used) nodes */
- size_type n;
+ /** @brief Total number of (used) nodes */
+ size_type n;
- /** @brief Rank of the last tree node that can be calculated
- taking into account a complete tree
- */
- size_type splitting_point;
+ /** @brief Rank of the last tree node that can be calculated
+ taking into account a complete tree
+ */
+ size_type splitting_point;
- /** @brief Rank of the tree root */
- size_type rank_root;
+ /** @brief Rank of the tree root */
+ size_type rank_root;
- /** @brief Height of the tree */
- int height;
+ /** @brief Height of the tree */
+ int height;
- /** @brief Number of threads into which divide the work */
- const thread_index_t num_threads;
+ /** @brief Number of threads into which divide the work */
+ const thread_index_t num_threads;
- /** @brief Helper object to mind potential gaps in r_init */
- const ranker& rank;
+ /** @brief Helper object to mind potential gaps in r_init */
+ const ranker& rank;
- /** @brief Constructor
- * @param r Array of nodes
- * @param _n Total number of (used) nodes
- * @param _num_threads Number of threads into which divide the work
- * @param _rank Helper object to mind potential gaps in @c r_init */
- nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n,
- const thread_index_t _num_threads, const ranker& _rank):
- r_init(r),
- n(_n),
- num_threads(_num_threads),
- rank(_rank)
- {
- height = log2(n);
- splitting_point = 2 * (n - ((1 << height) - 1)) -1;
+ /** @brief Constructor
+ * @param r Array of nodes
+ * @param _n Total number of (used) nodes
+ * @param _num_threads Number of threads into which divide the work
+ * @param _rank Helper object to mind potential gaps in @c r_init */
+ nodes_initializer(const _Rb_tree_node_ptr* r, const size_type _n,
+ const thread_index_t _num_threads,
+ const ranker& _rank)
+ : r_init(r), n(_n), num_threads(_num_threads), rank(_rank)
+ {
+ height = log2(n);
+ splitting_point = 2 * (n - ((1 << height) - 1)) -1;
- // Rank root.
- size_type max = 1 << (height + 1);
- rank_root= (max-2) >> 1;
- if (rank_root > splitting_point)
- rank_root = complete_to_original(rank_root);
+ // Rank root.
+ size_type max = 1 << (height + 1);
+ rank_root= (max-2) >> 1;
+ if (rank_root > splitting_point)
+ rank_root = complete_to_original(rank_root);
- mask[0] = 0x1;
- for (unsigned int i = 1; i < sizeof(size_type)*8; ++i)
- {
+ mask[0] = 0x1;
+ for (unsigned int i = 1; i < sizeof(size_type)*8; ++i)
mask[i] = (mask[i-1] << 1) + 1;
- }
- }
+ }
- /** @brief Query for tree height
- * @return Tree height */
- int
- get_height() const
- { return height; }
+ /** @brief Query for tree height
+ * @return Tree height */
+ int
+ get_height() const
+ { return height; }
- /** @brief Query for the splitting point
- * @return Splitting point */
- size_type
- get_shifted_splitting_point() const
- { return rank.get_shifted_rank(splitting_point, 0); }
+ /** @brief Query for the splitting point
+ * @return Splitting point */
+ size_type
+ get_shifted_splitting_point() const
+ { return rank.get_shifted_rank(splitting_point, 0); }
- /** @brief Query for the tree root node
- * @return Tree root node */
- _Rb_tree_node_ptr
- get_root() const
- { return r_init[rank.get_shifted_rank(rank_root,num_threads/2)]; }
+ /** @brief Query for the tree root node
+ * @return Tree root node */
+ _Rb_tree_node_ptr
+ get_root() const
+ { return r_init[rank.get_shifted_rank(rank_root,num_threads/2)]; }
- /** @brief Calculation of the parent position in the array of nodes
- * @hideinitializer */
+ /** @brief Calculation of the parent position in the array of nodes
+ * @hideinitializer */
#define CALCULATE_PARENT \
- if (p_s> splitting_point) \
- p_s = complete_to_original(p_s); \
- int s_r = rank.get_shifted_rank(p_s,iam); \
- r->_M_parent = r_init[s_r]; \
+ if (p_s> splitting_point) \
+ p_s = complete_to_original(p_s); \
+ int s_r = rank.get_shifted_rank(p_s,iam); \
+ r->_M_parent = r_init[s_r]; \
\
- /** @brief Link a node with its parent and children taking into
- account that its rank (without gaps) is different to that in
- a complete tree
- * @param r Pointer to the node
- * @param iam Partition of the array in which the node is, where
- * iam is in [0..num_threads)
- * @sa link_complete */
- void
- link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const
- {
- size_type real_pos = rank.get_real_rank(&r-r_init, iam);
- size_type l_s, r_s, p_s;
- int mod_pos= original_to_complete(real_pos);
- int zero= first_0_right(mod_pos);
-
- // 1. Convert n to n', where n' will be its rank if the tree
- // was complete
- // 2. Calculate neighbours for n'
- // 3. Convert the neighbors n1', n2' and n3' to their
- // appropriate values n1, n2, n3. Note that it must be
- // checked that these neighbors actually exist.
- calculate_shifts_pos_level(mod_pos, zero, l_s, r_s, p_s);
- if (l_s > splitting_point)
- {
- _GLIBCXX_PARALLEL_ASSERT(r_s > splitting_point);
- if (zero == 1)
- {
- r->_M_left = 0;
+ /** @brief Link a node with its parent and children taking into
+ account that its rank (without gaps) is different to that in
+ a complete tree
+ * @param r Pointer to the node
+ * @param iam Partition of the array in which the node is, where
+ * iam is in [0..num_threads)
+ * @sa link_complete */
+ void
+ link_incomplete(const _Rb_tree_node_ptr& r, const int iam) const
+ {
+ size_type real_pos = rank.get_real_rank(&r-r_init, iam);
+ size_type l_s, r_s, p_s;
+ int mod_pos= original_to_complete(real_pos);
+ int zero= first_0_right(mod_pos);
+
+ // 1. Convert n to n', where n' will be its rank if the tree
+ // was complete
+ // 2. Calculate neighbours for n'
+ // 3. Convert the neighbors n1', n2' and n3' to their
+ // appropriate values n1, n2, n3. Note that it must be
+ // checked that these neighbors actually exist.
+ calculate_shifts_pos_level(mod_pos, zero, l_s, r_s, p_s);
+ if (l_s > splitting_point)
+ {
+ _GLIBCXX_PARALLEL_ASSERT(r_s > splitting_point);
+ if (zero == 1)
+ {
+ r->_M_left = 0;
+ r->_M_right = 0;
+ }
+ else
+ {
+ r->_M_left =
+ r_init[rank.get_shifted_rank(complete_to_original(l_s),
+ iam)];
+ r->_M_right =
+ r_init[rank.get_shifted_rank(complete_to_original(r_s),
+ iam)];
+ }
+ }
+ else
+ {
+ r->_M_left= r_init[rank.get_shifted_rank(l_s,iam)];
+ if (zero != 1)
+ r->_M_right
+ = r_init[rank.get_shifted_rank(complete_to_original(r_s),
+ iam)];
+ else
r->_M_right = 0;
- }
- else
- {
- r->_M_left= r_init[rank.get_shifted_rank(complete_to_original(l_s),iam)];
- r->_M_right= r_init[rank.get_shifted_rank(complete_to_original(r_s),iam)];
- }
-
- }
- else{
- r->_M_left= r_init[rank.get_shifted_rank(l_s,iam)];
- if (zero != 1)
+ }
+ r->_M_color = std::_S_black;
+ CALCULATE_PARENT;
+ }
+
+ /** @brief Link a node with its parent and children taking into
+ account that its rank (without gaps) is the same as that in
+ a complete tree
+ * @param r Pointer to the node
+ * @param iam Partition of the array in which the node is, where
+ * iam is in [0..@c num_threads)
+ * @sa link_incomplete
+ */
+ void
+ link_complete(const _Rb_tree_node_ptr& r, const int iam) const
+ {
+ size_type real_pos = rank.get_real_rank(&r-r_init, iam);
+ size_type p_s;
+
+ // Test if it is a leaf on the last not necessarily full level
+ if ((real_pos & mask[0]) == 0)
{
- r->_M_right= r_init[rank.get_shifted_rank(complete_to_original(r_s),iam)];
+ if ((real_pos & 0x2) == 0)
+ p_s = real_pos + 1;
+ else
+ p_s = real_pos - 1;
+ r->_M_color = std::_S_red;
+ r->_M_left = 0;
+ r->_M_right = 0;
}
else
{
- r->_M_right = 0;
+ size_type l_s, r_s;
+ int zero = first_0_right(real_pos);
+ calculate_shifts_pos_level(real_pos, zero, l_s, r_s, p_s);
+ r->_M_color = std::_S_black;
+
+ r->_M_left = r_init[rank.get_shifted_rank(l_s,iam)];
+ if (r_s > splitting_point)
+ r_s = complete_to_original(r_s);
+ r->_M_right = r_init[rank.get_shifted_rank(r_s,iam)];
}
+ CALCULATE_PARENT;
}
- r->_M_color = std::_S_black;
- CALCULATE_PARENT;
- }
-
- /** @brief Link a node with its parent and children taking into
- account that its rank (without gaps) is the same as that in
- a complete tree
- * @param r Pointer to the node
- * @param iam Partition of the array in which the node is, where
- * iam is in [0..@c num_threads)
- * @sa link_incomplete
- */
- void
- link_complete(const _Rb_tree_node_ptr& r, const int iam) const
- {
- size_type real_pos = rank.get_real_rank(&r-r_init, iam);
- size_type p_s;
-
- // Test if it is a leaf on the last not necessarily full level
- if ((real_pos & mask[0]) == 0)
- {
- if ((real_pos & 0x2) == 0)
- p_s = real_pos + 1;
- else
- p_s = real_pos - 1;
- r->_M_color = std::_S_red;
- r->_M_left = 0;
- r->_M_right = 0;
- }
- else
- {
- size_type l_s, r_s;
- int zero = first_0_right(real_pos);
- calculate_shifts_pos_level(real_pos, zero, l_s, r_s, p_s);
- r->_M_color = std::_S_black;
-
- r->_M_left = r_init[rank.get_shifted_rank(l_s,iam)];
- if (r_s > splitting_point)
- r_s = complete_to_original(r_s);
- r->_M_right = r_init[rank.get_shifted_rank(r_s,iam)];
- }
- CALCULATE_PARENT;
- }
#undef CALCULATE_PARENT
- private:
- /** @brief Change of "base": Convert the rank in the actual tree
- into the corresponding rank if the tree was complete
- * @param pos Rank in the actual incomplete tree
- * @return Rank in the corresponding complete tree
- * @sa complete_to_original */
- int
- original_to_complete(const int pos) const
- { return (pos << 1) - splitting_point; }
-
- /** @brief Change of "base": Convert the rank if the tree was
- complete into the corresponding rank in the actual tree
- * @param pos Rank in the complete tree
- * @return Rank in the actual incomplete tree
- * @sa original_to_complete */
- int
- complete_to_original(const int pos) const
- { return (pos + splitting_point) >> 1; }
-
-
- /** @brief Calculate the rank in the complete tree of the parent
- and children of a node
- * @param pos Rank in the complete tree of the node whose parent
- * and children rank must be calculated
- * @param level Tree level in which the node at pos is in
- * (starting to count at leaves). @pre @c level > 1
- * @param left_shift Rank in the complete tree of the left child
- * of pos (out parameter)
- * @param right_shift Rank in the complete tree of the right
- * child of pos (out parameter)
- * @param parent_shift Rank in the complete tree of the parent
- * of pos (out parameter)
- */
- void
- calculate_shifts_pos_level(const size_type pos, const int level,
- size_type& left_shift, size_type& right_shift,
- size_type& parent_shift) const
- {
- int stride = 1 << (level -1);
- left_shift = pos - stride;
- right_shift = pos + stride;
- if (((pos >> (level + 1)) & 0x1) == 0)
- parent_shift = pos + 2*stride;
- else
- parent_shift = pos - 2*stride;
- }
-
- /** @brief Search for the first 0 bit (growing the weight)
- * @param x Binary number (corresponding to a rank in the tree)
- * whose first 0 bit must be calculated
- * @return Position of the first 0 bit in @c x (starting to
- * count with 1)
- */
- int
- first_0_right(const size_type x) const
- {
- if ((x & 0x2) == 0)
- return 1;
- else
- return first_0_right_bs(x);
- }
+ private:
+ /** @brief Change of "base": Convert the rank in the actual tree
+ into the corresponding rank if the tree was complete
+ * @param pos Rank in the actual incomplete tree
+ * @return Rank in the corresponding complete tree
+ * @sa complete_to_original */
+ int
+ original_to_complete(const int pos) const
+ { return (pos << 1) - splitting_point; }
+
+ /** @brief Change of "base": Convert the rank if the tree was
+ complete into the corresponding rank in the actual tree
+ * @param pos Rank in the complete tree
+ * @return Rank in the actual incomplete tree
+ * @sa original_to_complete */
+ int
+ complete_to_original(const int pos) const
+ { return (pos + splitting_point) >> 1; }
+
+
+ /** @brief Calculate the rank in the complete tree of the parent
+ and children of a node
+ * @param pos Rank in the complete tree of the node whose parent
+ * and children rank must be calculated
+ * @param level Tree level in which the node at pos is in
+ * (starting to count at leaves). @pre @c level > 1
+ * @param left_shift Rank in the complete tree of the left child
+ * of pos (out parameter)
+ * @param right_shift Rank in the complete tree of the right
+ * child of pos (out parameter)
+ * @param parent_shift Rank in the complete tree of the parent
+ * of pos (out parameter)
+ */
+ void
+ calculate_shifts_pos_level(const size_type pos, const int level,
+ size_type& left_shift,
+ size_type& right_shift,
+ size_type& parent_shift) const
+ {
+ int stride = 1 << (level -1);
+ left_shift = pos - stride;
+ right_shift = pos + stride;
+ if (((pos >> (level + 1)) & 0x1) == 0)
+ parent_shift = pos + 2*stride;
+ else
+ parent_shift = pos - 2*stride;
+ }
- /** @brief Search for the first 0 bit (growing the weight) using
- * binary search
- *
- * Binary search can be used instead of a naive loop using the
- * masks in mask array
- * @param x Binary number (corresponding to a rank in the tree)
- * whose first 0 bit must be calculated
- * @param k_beg Position in which to start searching. By default is 2.
- * @return Position of the first 0 bit in x (starting to count with 1) */
- int
- first_0_right_bs(const size_type x, int k_beg=2) const
- {
- int k_end = sizeof(size_type)*8;
- size_type not_x = x ^ mask[k_end-1];
- while ((k_end-k_beg) > 1)
- {
- int k = k_beg + (k_end-k_beg)/2;
- if ((not_x & mask[k-1]) != 0)
- k_end = k;
- else
- k_beg = k;
- }
- return k_beg;
- }
+ /** @brief Search for the first 0 bit (growing the weight)
+ * @param x Binary number (corresponding to a rank in the tree)
+ * whose first 0 bit must be calculated
+ * @return Position of the first 0 bit in @c x (starting to
+ * count with 1)
+ */
+ int
+ first_0_right(const size_type x) const
+ {
+ if ((x & 0x2) == 0)
+ return 1;
+ else
+ return first_0_right_bs(x);
+ }
+
+ /** @brief Search for the first 0 bit (growing the weight) using
+ * binary search
+ *
+ * Binary search can be used instead of a naive loop using the
+ * masks in mask array
+ * @param x Binary number (corresponding to a rank in the tree)
+ * whose first 0 bit must be calculated
+ * @param k_beg Position in which to start searching. By default is 2.
+ * @return Position of the first 0 bit in x (starting to count with 1) */
+ int
+ first_0_right_bs(const size_type x, int k_beg=2) const
+ {
+ int k_end = sizeof(size_type)*8;
+ size_type not_x = x ^ mask[k_end-1];
+ while ((k_end-k_beg) > 1)
+ {
+ int k = k_beg + (k_end-k_beg)/2;
+ if ((not_x & mask[k-1]) != 0)
+ k_end = k;
+ else
+ k_beg = k;
+ }
+ return k_beg;
+ }
};
/***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
* @param _num_threads Number of partitions (and threads that
* work on it) */
ranker_gaps(const size_type* size_p, const size_type* shift_r,
- const thread_index_t _num_threads) :
- beg_shift_partition(size_p),
- rank_shift(shift_r),
+ const thread_index_t _num_threads)
+ : beg_shift_partition(size_p), rank_shift(shift_r),
num_threads(_num_threads)
{
beg_partition = new size_type[num_threads+1];
beg_partition[0] = 0;
for (int i = 1; i <= num_threads; ++i)
- {
- beg_partition[i] = beg_partition[i-1] + (beg_shift_partition[i] - beg_shift_partition[i-1]) - (rank_shift[i] - rank_shift[i-1]);
-
- }
+ beg_partition[i] = (beg_partition[i-1]
+ + (beg_shift_partition[i]
+ - beg_shift_partition[i-1])
+ - (rank_shift[i] - rank_shift[i-1]));
// Ghost element, strictly larger than any index requested.
++beg_partition[num_threads];
* @param _Comp Comparator to invert
* @param _Iterator Iterator to the elements to compare */
template<typename _Comp, typename _Iterator>
- class gr_or_eq
- {
- /** @brief Renaming value_type of _Iterator */
- typedef typename std::iterator_traits<_Iterator>::value_type value_type;
-
- /** @brief Comparator to be inverted */
- const _Comp comp;
-
- public:
- /** @brief Constructor
- * @param c Comparator */
- gr_or_eq(const _Comp& c) : comp(c) { }
-
- /** @brief Operator()
- * @param a First value to compare
- * @param b Second value to compare */
- bool operator()(const value_type& a, const value_type& b) const
+ class gr_or_eq
{
- if (not (comp(_KeyOfValue()(a), _KeyOfValue()(b))))
- return true;
- return false;
- }
- };
+ /** @brief Renaming value_type of _Iterator */
+ typedef typename std::iterator_traits<_Iterator>::value_type
+ value_type;
+
+ /** @brief Comparator to be inverted */
+ const _Comp comp;
+
+ public:
+ /** @brief Constructor
+ * @param c Comparator */
+ gr_or_eq(const _Comp& c) : comp(c) { }
+
+ /** @brief Operator()
+ * @param a First value to compare
+ * @param b Second value to compare */
+ bool
+ operator()(const value_type& a, const value_type& b) const
+ {
+ if (not (comp(_KeyOfValue()(a), _KeyOfValue()(b))))
+ return true;
+ return false;
+ }
+ };
/** @brief Helper comparator class: Passed as a parameter of
list_partition to check that a sequence is sorted
* @param _InputIterator Iterator to the elements to compare
* @param _CompIsSorted Comparator to check for sortednesss */
template<typename _InputIterator, typename _CompIsSorted>
- class is_sorted_functor
- {
- /** @brief Element to compare with (first parameter of comp) */
- _InputIterator prev;
-
- /** @brief Comparator to check for sortednesss */
- const _CompIsSorted comp;
-
- /** @brief Sum up the history of the operator() of this
- * comparator class Its value is true if all calls to comp from
- * this class have returned true. It is false otherwise */
- bool sorted;
-
- public:
- /** @brief Constructor
- *
- * Sorted is set to true
- * @param first Element to compare with the first time the
- * operator() is called
- * @param c Comparator to check for sortedness */
- is_sorted_functor(const _InputIterator first, const _CompIsSorted c)
- : prev(first), comp(c), sorted(true) { }
-
- /** @brief Operator() with only one explicit parameter. Updates
- the class member @c prev and sorted.
- * @param it Iterator to the element which must be compared to
- * the element pointed by the the class member @c prev */
- void operator()(const _InputIterator it)
+ class is_sorted_functor
{
- if (sorted and it != prev and comp(_KeyOfValue()(*it),
- _KeyOfValue()(*prev)))
- sorted = false;
- prev = it;
- }
+ /** @brief Element to compare with (first parameter of comp) */
+ _InputIterator prev;
+
+ /** @brief Comparator to check for sortednesss */
+ const _CompIsSorted comp;
+
+ /** @brief Sum up the history of the operator() of this
+ * comparator class Its value is true if all calls to comp from
+ * this class have returned true. It is false otherwise */
+ bool sorted;
+
+ public:
+ /** @brief Constructor
+ *
+ * Sorted is set to true
+ * @param first Element to compare with the first time the
+ * operator() is called
+ * @param c Comparator to check for sortedness */
+ is_sorted_functor(const _InputIterator first, const _CompIsSorted c)
+ : prev(first), comp(c), sorted(true) { }
+
+ /** @brief Operator() with only one explicit parameter. Updates
+ the class member @c prev and sorted.
+ * @param it Iterator to the element which must be compared to
+ * the element pointed by the the class member @c prev */
+ void
+ operator()(const _InputIterator it)
+ {
+ if (sorted and it != prev and comp(_KeyOfValue()(*it),
+ _KeyOfValue()(*prev)))
+ sorted = false;
+ prev = it;
+ }
- /** @brief Query method for sorted
- * @return Current value of sorted */
- bool is_sorted() const
- {
- return sorted;
- }
- };
+ /** @brief Query method for sorted
+ * @return Current value of sorted */
+ bool
+ is_sorted() const
+ { return sorted; }
+ };
/** @brief Helper functor: sort the input based upon elements
instead of keys
* @param KeyComparator Comparator for the key of values */
template<typename KeyComparator>
- class ValueCompare
- : public std::binary_function<value_type, value_type, bool>
- {
- /** @brief Comparator for the key of values */
- const KeyComparator comp;
-
- public:
- /** @brief Constructor
- * @param c Comparator for the key of values */
- ValueCompare(const KeyComparator& c): comp(c) { }
-
- /** @brief Operator(): Analogous to comp but for values and not keys
- * @param v1 First value to compare
- * @param v2 Second value to compare
- * @return Result of the comparison */
- bool operator()(const value_type& v1, const value_type& v2) const
- { return comp(_KeyOfValue()(v1),_KeyOfValue()(v2)); }
- };
+ class ValueCompare
+ : public std::binary_function<value_type, value_type, bool>
+ {
+ /** @brief Comparator for the key of values */
+ const KeyComparator comp;
+
+ public:
+ /** @brief Constructor
+ * @param c Comparator for the key of values */
+ ValueCompare(const KeyComparator& c): comp(c) { }
+
+ /** @brief Operator(): Analogous to comp but for values and not keys
+ * @param v1 First value to compare
+ * @param v2 Second value to compare
+ * @return Result of the comparison */
+ bool
+ operator()(const value_type& v1, const value_type& v2) const
+ { return comp(_KeyOfValue()(v1),_KeyOfValue()(v2)); }
+ };
/** @brief Helper comparator: compare a key with the key in a node
* @param _Comparator Comparator for keys */
template<typename _Comparator>
- struct compare_node_key
- {
- /** @brief Comparator for keys */
- const _Comparator& c;
-
- /** @brief Constructor
- * @param _c Comparator for keys */
- compare_node_key(const _Comparator& _c) : c(_c) { }
-
- /** @brief Operator() with the first parameter being a node
- * @param r Node whose key is to be compared
- * @param k Key to be compared
- * @return Result of the comparison */
- bool operator()(const _Rb_tree_node_ptr r, const key_type& k) const
- { return c(base_type::_S_key(r),k); }
-
- /** @brief Operator() with the second parameter being a node
- * @param k Key to be compared
- * @param r Node whose key is to be compared
- * @return Result of the comparison */
- bool operator()(const key_type& k, const _Rb_tree_node_ptr r) const
- { return c(k, base_type::_S_key(r)); }
- };
+ struct compare_node_key
+ {
+ /** @brief Comparator for keys */
+ const _Comparator& c;
+
+ /** @brief Constructor
+ * @param _c Comparator for keys */
+ compare_node_key(const _Comparator& _c) : c(_c) { }
+
+ /** @brief Operator() with the first parameter being a node
+ * @param r Node whose key is to be compared
+ * @param k Key to be compared
+ * @return Result of the comparison */
+ bool
+ operator()(const _Rb_tree_node_ptr r, const key_type& k) const
+ { return c(base_type::_S_key(r),k); }
+
+ /** @brief Operator() with the second parameter being a node
+ * @param k Key to be compared
+ * @param r Node whose key is to be compared
+ * @return Result of the comparison */
+ bool
+ operator()(const key_type& k, const _Rb_tree_node_ptr r) const
+ { return c(k, base_type::_S_key(r)); }
+ };
/** @brief Helper comparator: compare a key with the key of a
value pointed by an iterator
* @param _Comparator Comparator for keys
*/
template<typename _Iterator, typename _Comparator>
- struct compare_value_key
- {
- /** @brief Comparator for keys */
- const _Comparator& c;
-
- /** @brief Constructor
- * @param _c Comparator for keys */
- compare_value_key(const _Comparator& _c) : c(_c){ }
-
- /** @brief Operator() with the first parameter being an iterator
- * @param v Iterator to the value whose key is to be compared
- * @param k Key to be compared
- * @return Result of the comparison */
- bool operator()(const _Iterator& v, const key_type& k) const
- { return c(_KeyOfValue()(*v),k); }
-
- /** @brief Operator() with the second parameter being an iterator
- * @param k Key to be compared
- * @param v Iterator to the value whose key is to be compared
- * @return Result of the comparison */
- bool operator()(const key_type& k, const _Iterator& v) const
- { return c(k, _KeyOfValue()(*v)); }
- };
+ struct compare_value_key
+ {
+ /** @brief Comparator for keys */
+ const _Comparator& c;
+
+ /** @brief Constructor
+ * @param _c Comparator for keys */
+ compare_value_key(const _Comparator& _c) : c(_c){ }
+
+ /** @brief Operator() with the first parameter being an iterator
+ * @param v Iterator to the value whose key is to be compared
+ * @param k Key to be compared
+ * @return Result of the comparison */
+ bool
+ operator()(const _Iterator& v, const key_type& k) const
+ { return c(_KeyOfValue()(*v),k); }
+
+ /** @brief Operator() with the second parameter being an iterator
+ * @param k Key to be compared
+ * @param v Iterator to the value whose key is to be compared
+ * @return Result of the comparison */
+ bool
+ operator()(const key_type& k, const _Iterator& v) const
+ { return c(k, _KeyOfValue()(*v)); }
+ };
/** @brief Helper class of _Rb_tree to avoid some symmetric code
in tree operations */
/** @brief Obtain the conceptual left child of a node
* @param parent Node whose child must be obtained
* @return Reference to the child node */
- static _Rb_tree_node_base*& left(_Rb_tree_node_base* parent)
+ static _Rb_tree_node_base*&
+ left(_Rb_tree_node_base* parent)
{ return parent->_M_left; }
/** @brief Obtain the conceptual right child of a node
* @param parent Node whose child must be obtained
* @return Reference to the child node */
- static _Rb_tree_node_base*& right(_Rb_tree_node_base* parent)
+ static _Rb_tree_node_base*&
+ right(_Rb_tree_node_base* parent)
{ return parent->_M_right; }
};
* @param S Symmetry to inverse
* @sa LeftRight */
template<typename S>
- struct Opposite
- {
- /** @brief Obtain the conceptual left child of a node, inverting
- the symmetry
- * @param parent Node whose child must be obtained
- * @return Reference to the child node */
- static _Rb_tree_node_base*& left(_Rb_tree_node_base* parent)
- { return S::right(parent);}
-
- /** @brief Obtain the conceptual right child of a node,
- inverting the symmetry
- * @param parent Node whose child must be obtained
- * @return Reference to the child node */
- static _Rb_tree_node_base*& right(_Rb_tree_node_base* parent)
- { return S::left(parent);}
- };
+ struct Opposite
+ {
+ /** @brief Obtain the conceptual left child of a node, inverting
+ the symmetry
+ * @param parent Node whose child must be obtained
+ * @return Reference to the child node */
+ static _Rb_tree_node_base*&
+ left(_Rb_tree_node_base* parent)
+ { return S::right(parent);}
+
+ /** @brief Obtain the conceptual right child of a node,
+ inverting the symmetry
+ * @param parent Node whose child must be obtained
+ * @return Reference to the child node */
+ static _Rb_tree_node_base*&
+ right(_Rb_tree_node_base* parent)
+ { return S::left(parent);}
+ };
/** @brief Inverse symmetry of LeftRight */
typedef Opposite<LeftRight> RightLeft;
* @param Comparator Comparator for values
* @param _ValuePtr Pointer to values */
template<typename Comparator, typename _ValuePtr>
- class PtrComparator
- : public std::binary_function<_ValuePtr, _ValuePtr, bool>
- {
- /** @brief Comparator for values */
- Comparator comp;
-
- public:
- /** @brief Constructor
- * @param comp Comparator for values */
- PtrComparator(Comparator comp) : comp(comp) { }
-
- /** @brief Operator(): compare the values instead of the pointers
- * @param v1 Pointer to the first element to compare
- * @param v2 Pointer to the second element to compare */
- bool operator()(const _ValuePtr& v1, const _ValuePtr& v2) const
- { return comp(*v1,*v2); }
- };
+ class PtrComparator
+ : public std::binary_function<_ValuePtr, _ValuePtr, bool>
+ {
+ /** @brief Comparator for values */
+ Comparator comp;
+
+ public:
+ /** @brief Constructor
+ * @param comp Comparator for values */
+ PtrComparator(Comparator comp) : comp(comp) { }
+
+ /** @brief Operator(): compare the values instead of the pointers
+ * @param v1 Pointer to the first element to compare
+ * @param v2 Pointer to the second element to compare */
+ bool
+ operator()(const _ValuePtr& v1, const _ValuePtr& v2) const
+ { return comp(*v1,*v2); }
+ };
/** @brief Iterator whose elements are pointers
* @param value_type Type pointed by the pointers */
template<typename _ValueTp>
- class PtrIterator
- {
- public:
- /** @brief The iterator category is random access iterator */
- typedef typename std::random_access_iterator_tag iterator_category;
- typedef _ValueTp value_type;
- typedef size_t difference_type;
- typedef value_type* ValuePtr;
- typedef ValuePtr& reference;
- typedef value_type** pointer;
+ class PtrIterator
+ {
+ public:
+ /** @brief The iterator category is random access iterator */
+ typedef typename std::random_access_iterator_tag iterator_category;
+ typedef _ValueTp value_type;
+ typedef size_t difference_type;
+ typedef value_type* ValuePtr;
+ typedef ValuePtr& reference;
+ typedef value_type** pointer;
- /** @brief Element accessed by the iterator */
- value_type** ptr;
+ /** @brief Element accessed by the iterator */
+ value_type** ptr;
- /** @brief Trivial constructor */
- PtrIterator() { }
+ /** @brief Trivial constructor */
+ PtrIterator() { }
- /** @brief Constructor from an element */
- PtrIterator(const ValuePtr& __i) : ptr(&__i) { }
+ /** @brief Constructor from an element */
+ PtrIterator(const ValuePtr& __i) : ptr(&__i) { }
- /** @brief Constructor from a pointer */
- PtrIterator(const pointer& __i) : ptr(__i) { }
+ /** @brief Constructor from a pointer */
+ PtrIterator(const pointer& __i) : ptr(__i) { }
- /** @brief Copy constructor */
- PtrIterator(const PtrIterator<value_type>& __i) : ptr(__i.ptr) { }
+ /** @brief Copy constructor */
+ PtrIterator(const PtrIterator<value_type>& __i) : ptr(__i.ptr) { }
- reference
- operator*() const
- { return **ptr; }
+ reference
+ operator*() const
+ { return **ptr; }
- ValuePtr
- operator->() const
- { return *ptr; }
+ ValuePtr
+ operator->() const
+ { return *ptr; }
- /** @brief Bidirectional iterator requirement */
- PtrIterator&
- operator++()
- {
- ++ptr;
- return *this;
- }
+ /** @brief Bidirectional iterator requirement */
+ PtrIterator&
+ operator++()
+ {
+ ++ptr;
+ return *this;
+ }
- /** @brief Bidirectional iterator requirement */
- PtrIterator
- operator++(int)
- { return PtrIterator(ptr++); }
+ /** @brief Bidirectional iterator requirement */
+ PtrIterator
+ operator++(int)
+ { return PtrIterator(ptr++); }
- /** @brief Bidirectional iterator requirement */
- PtrIterator&
- operator--()
- {
- --ptr;
- return *this;
- }
+ /** @brief Bidirectional iterator requirement */
+ PtrIterator&
+ operator--()
+ {
+ --ptr;
+ return *this;
+ }
- /** @brief Bidirectional iterator requirement */
- PtrIterator
- operator--(int)
- { return PtrIterator(ptr--); }
+ /** @brief Bidirectional iterator requirement */
+ PtrIterator
+ operator--(int)
+ { return PtrIterator(ptr--); }
- /** @brief Random access iterator requirement */
- reference
- operator[](const difference_type& __n) const
- { return *ptr[__n]; }
+ /** @brief Random access iterator requirement */
+ reference
+ operator[](const difference_type& __n) const
+ { return *ptr[__n]; }
- /** @brief Random access iterator requirement */
- PtrIterator&
- operator+=(const difference_type& __n)
- {
- ptr += __n;
- return *this;
- }
+ /** @brief Random access iterator requirement */
+ PtrIterator&
+ operator+=(const difference_type& __n)
+ {
+ ptr += __n;
+ return *this;
+ }
- /** @brief Random access iterator requirement */
- PtrIterator
- operator+(const difference_type& __n) const
- { return PtrIterator(ptr + __n); }
+ /** @brief Random access iterator requirement */
+ PtrIterator
+ operator+(const difference_type& __n) const
+ { return PtrIterator(ptr + __n); }
- /** @brief Random access iterator requirement */
- PtrIterator&
- operator-=(const difference_type& __n)
- {
- ptr -= __n;
- return *this;
- }
+ /** @brief Random access iterator requirement */
+ PtrIterator&
+ operator-=(const difference_type& __n)
+ {
+ ptr -= __n;
+ return *this;
+ }
- /** @brief Random access iterator requirement */
- PtrIterator
- operator-(const difference_type& __n) const
- { return PtrIterator(ptr - __n); }
+ /** @brief Random access iterator requirement */
+ PtrIterator
+ operator-(const difference_type& __n) const
+ { return PtrIterator(ptr - __n); }
- /** @brief Random access iterator requirement */
- difference_type
- operator-(const PtrIterator<value_type>& iter) const
- { return ptr - iter.ptr; }
+ /** @brief Random access iterator requirement */
+ difference_type
+ operator-(const PtrIterator<value_type>& iter) const
+ { return ptr - iter.ptr; }
- /** @brief Random access iterator requirement */
- difference_type
- operator+(const PtrIterator<value_type>& iter) const
- { return ptr + iter.ptr; }
+ /** @brief Random access iterator requirement */
+ difference_type
+ operator+(const PtrIterator<value_type>& iter) const
+ { return ptr + iter.ptr; }
- /** @brief Allow assignment of an element ValuePtr to the iterator */
- PtrIterator<value_type>& operator=(const ValuePtr sptr)
- {
- ptr = &sptr;
- return *this;
- }
+ /** @brief Allow assignment of an element ValuePtr to the iterator */
+ PtrIterator<value_type>&
+ operator=(const ValuePtr sptr)
+ {
+ ptr = &sptr;
+ return *this;
+ }
- PtrIterator<value_type>& operator=(const PtrIterator<value_type>& piter)
- {
- ptr = piter.ptr;
- return *this;
- }
+ PtrIterator<value_type>&
+ operator=(const PtrIterator<value_type>& piter)
+ {
+ ptr = piter.ptr;
+ return *this;
+ }
- bool operator==(const PtrIterator<value_type>& piter)
- { return ptr == piter.ptr; }
+ bool
+ operator==(const PtrIterator<value_type>& piter)
+ { return ptr == piter.ptr; }
- bool operator!=(const PtrIterator<value_type>& piter)
- { return ptr != piter.ptr; }
+ bool
+ operator!=(const PtrIterator<value_type>& piter)
+ { return ptr != piter.ptr; }
- };
+ };
/** @brief Bulk insertion helper: synchronization and construction
* saved so that afterwards the sequence can be processed
* effectively in parallel. */
template<typename _InputIterator, typename StrictlyLessOrLessEqual>
- void
- _M_bulk_insertion_construction(const _InputIterator __first, const _InputIterator __last, const bool is_construction, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- thread_index_t num_threads = get_max_threads();
- size_type n;
- size_type beg_partition[num_threads+1];
- _InputIterator access[num_threads+1];
- beg_partition[0] = 0;
- bool is_sorted= is_sorted_distance_accessors(__first, __last, access, beg_partition,n, num_threads, std::__iterator_category(__first));
-
- if (not is_sorted)
- {
- _M_not_sorted_bulk_insertion_construction(access, beg_partition, n, num_threads, is_construction, strictly_less_or_less_equal);
- }
- else
- {
- // The vector must be moved... all ranges must have at least
- // one element, or make just sequential???
- if (static_cast<size_type>(num_threads) > n)
- {
- int j = 1;
- for (int i = 1; i <= num_threads; ++i)
- {
- if (beg_partition[j-1] != beg_partition[i])
- {
- beg_partition[j] = beg_partition[i];
- access[j] = access[i];
- ++j;
- }
- }
- num_threads = static_cast<thread_index_t>(n);
- }
+ void
+ _M_bulk_insertion_construction(const _InputIterator __first,
+ const _InputIterator __last,
+ const bool is_construction,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ thread_index_t num_threads = get_max_threads();
+ size_type n;
+ size_type beg_partition[num_threads+1];
+ _InputIterator access[num_threads+1];
+ beg_partition[0] = 0;
+ bool is_sorted =
+ is_sorted_distance_accessors(__first, __last, access,
+ beg_partition, n, num_threads,
+ std::__iterator_category(__first));
+
+ if (not is_sorted)
+ _M_not_sorted_bulk_insertion_construction(
+ access, beg_partition, n, num_threads,
+ is_construction, strictly_less_or_less_equal);
+ else
+ {
+ // The vector must be moved... all ranges must have at least
+ // one element, or make just sequential???
+ if (static_cast<size_type>(num_threads) > n)
+ {
+ int j = 1;
+ for (int i = 1; i <= num_threads; ++i)
+ {
+ if (beg_partition[j-1] != beg_partition[i])
+ {
+ beg_partition[j] = beg_partition[i];
+ access[j] = access[i];
+ ++j;
+ }
+ }
+ num_threads = static_cast<thread_index_t>(n);
+ }
- if (is_construction)
- _M_sorted_bulk_construction(access, beg_partition, n, num_threads,
- strictly_less_or_less_equal);
- else
- _M_sorted_bulk_insertion(access, beg_partition, n, num_threads,
- strictly_less_or_less_equal);
- }
- }
+ if (is_construction)
+ _M_sorted_bulk_construction(access, beg_partition, n,
+ num_threads,
+ strictly_less_or_less_equal);
+ else
+ _M_sorted_bulk_insertion(access, beg_partition, n, num_threads,
+ strictly_less_or_less_equal);
+ }
+ }
/** @brief Bulk construction and insertion helper method on an
* input sequence which is not sorted
* of the wrapping container
*/
template<typename _InputIterator, typename StrictlyLessOrLessEqual>
- void
- _M_not_sorted_bulk_insertion_construction(_InputIterator* access,
- size_type* beg_partition,
- const size_type n,
- const thread_index_t num_threads,
- const bool is_construction,
- StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- // Copy entire elements. In the case of a map, we would be
- // copying the pair. Therefore, the copy should be reconsidered
- // when objects are big. Essentially two cases:
- // - The key is small: make that the pair, is a pointer to data
- // instead of a copy to it
- // - The key is big: we simply have a pointer to the iterator
+ void
+ _M_not_sorted_bulk_insertion_construction(_InputIterator* access,
+ size_type* beg_partition,
+ const size_type n,
+ const thread_index_t
+ num_threads,
+ const bool is_construction,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ // Copy entire elements. In the case of a map, we would be
+ // copying the pair. Therefore, the copy should be reconsidered
+ // when objects are big. Essentially two cases:
+ // - The key is small: make that the pair, is a pointer to data
+ // instead of a copy to it
+ // - The key is big: we simply have a pointer to the iterator
#if _GLIBCXX_TREE_FULL_COPY
- nc_value_type* v = static_cast<nc_value_type*> (::operator new(sizeof(nc_value_type)*(n+1)));
-
- uninitialized_copy_from_accessors(access, beg_partition, v, num_threads);
-
- _M_not_sorted_bulk_insertion_construction<nc_value_type, nc_value_type*, ValueCompare<_Compare> >
- (beg_partition, v, ValueCompare<_Compare>(base_type::_M_impl._M_key_compare), n, num_threads, is_construction, strictly_less_or_less_equal);
+ nc_value_type* v =
+ static_cast<nc_value_type*>(::operator new(sizeof(nc_value_type)
+ * (n+1)));
+
+ uninitialized_copy_from_accessors(access, beg_partition,
+ v, num_threads);
+
+ _M_not_sorted_bulk_insertion_construction<nc_value_type,
+ nc_value_type*, ValueCompare<_Compare> >
+ (beg_partition, v, ValueCompare<_Compare>(base_type::
+ _M_impl._M_key_compare),
+ n, num_threads, is_construction, strictly_less_or_less_equal);
#else
- // For sorting, we cannot use the new PtrIterator because we
- // want the pointers to be exchanged and not the elements.
- typedef PtrComparator<ValueCompare<_Compare>, nc_value_type*> this_ptr_comparator;
- nc_value_type** v = static_cast<nc_value_type**> (::operator new(sizeof(nc_value_type*)*(n+1)));
-
- uninitialized_ptr_copy_from_accessors(access, beg_partition, v, num_threads);
-
- _M_not_sorted_bulk_insertion_construction<nc_value_type*, PtrIterator<nc_value_type>, this_ptr_comparator>
- (beg_partition, v, this_ptr_comparator(ValueCompare<_Compare>(base_type::_M_impl._M_key_compare)), n, num_threads, is_construction, strictly_less_or_less_equal);
+ // For sorting, we cannot use the new PtrIterator because we
+ // want the pointers to be exchanged and not the elements.
+ typedef PtrComparator<ValueCompare<_Compare>, nc_value_type*>
+ this_ptr_comparator;
+ nc_value_type** v =
+ static_cast<nc_value_type**>(::operator new(sizeof(nc_value_type*)
+ * (n+1)));
+
+ uninitialized_ptr_copy_from_accessors(access, beg_partition,
+ v, num_threads);
+
+ _M_not_sorted_bulk_insertion_construction<nc_value_type*,
+ PtrIterator<nc_value_type>, this_ptr_comparator>
+ (beg_partition, v, this_ptr_comparator(
+ ValueCompare<_Compare>(base_type::_M_impl._M_key_compare)),
+ n, num_threads, is_construction, strictly_less_or_less_equal);
#endif
- }
+ }
/** @brief Bulk construction and insertion helper method on an
* input sequence which is not sorted
* transparently with repetitions with respect to the uniqueness
* of the wrapping container
*/
- template<typename ElementsToSort, typename IteratorSortedElements, typename Comparator, typename StrictlyLessOrLessEqual>
- void
- _M_not_sorted_bulk_insertion_construction(size_type* beg_partition, ElementsToSort* v, Comparator comp, const size_type n, thread_index_t num_threads, const bool is_construction, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- // The accessors have been calculated for the non sorted.
- num_threads = static_cast<thread_index_t>(std::min<size_type>(num_threads, n));
-
- std::stable_sort(v, v+n, comp);
-
- IteratorSortedElements sorted_access[num_threads+1];
- range_accessors(IteratorSortedElements(v), IteratorSortedElements(v+n), sorted_access, beg_partition, n, num_threads, std::__iterator_category(v));
-
- // Partial template specialization not available.
- if (is_construction)
- _M_sorted_bulk_construction(sorted_access, beg_partition, n, num_threads, strictly_less_or_less_equal);
- else
- _M_sorted_bulk_insertion(sorted_access, beg_partition, n, num_threads, strictly_less_or_less_equal);
- ::operator delete(v);
- }
+ template<typename ElementsToSort, typename IteratorSortedElements,
+ typename Comparator, typename StrictlyLessOrLessEqual>
+ void
+ _M_not_sorted_bulk_insertion_construction(size_type* beg_partition,
+ ElementsToSort* v,
+ Comparator comp,
+ const size_type n,
+ thread_index_t num_threads,
+ const bool is_construction,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ // The accessors have been calculated for the non sorted.
+ num_threads =
+ static_cast<thread_index_t>(std::min<size_type>(num_threads, n));
+
+ std::stable_sort(v, v+n, comp);
+
+ IteratorSortedElements sorted_access[num_threads+1];
+ range_accessors(IteratorSortedElements(v),
+ IteratorSortedElements(v + n),
+ sorted_access, beg_partition, n, num_threads,
+ std::__iterator_category(v));
+
+ // Partial template specialization not available.
+ if (is_construction)
+ _M_sorted_bulk_construction(sorted_access, beg_partition, n,
+ num_threads,
+ strictly_less_or_less_equal);
+ else
+ _M_sorted_bulk_insertion(sorted_access, beg_partition, n,
+ num_threads, strictly_less_or_less_equal);
+ ::operator delete(v);
+ }
/** @brief Construct a tree sequentially using the parallel routine
* @param r_array Array of nodes from which to take the nodes to
* going to be shared
*/
template<typename _Iterator>
- _Rb_tree_node_ptr*
- _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access, const size_type* beg_partition, const size_type n, const thread_index_t num_threads)
- {
- _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1)));
+ _Rb_tree_node_ptr*
+ _M_unsorted_bulk_allocation_and_initialization(const _Iterator* access,
+ const size_type*
+ beg_partition,
+ const size_type n,
+ const thread_index_t
+ num_threads)
+ {
+ _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>(
+ ::operator new (sizeof(_Rb_tree_node_ptr) * (n + 1)));
- // Allocate and initialize the nodes (don't check for uniqueness
- // because the sequence is not necessarily sorted.
+ // Allocate and initialize the nodes (don't check for uniqueness
+ // because the sequence is not necessarily sorted.
#pragma omp parallel num_threads(num_threads)
- {
+ {
#if USE_PAPI
- PAPI_register_thread();
+ PAPI_register_thread();
#endif
- int iam = omp_get_thread_num();
- _Iterator it = access[iam];
- size_type i = beg_partition[iam];
- while (it!= access[iam+1])
- {
- r[i] = base_type::_M_create_node(*it);
- ++i;
- ++it;
- }
+ int iam = omp_get_thread_num();
+ _Iterator it = access[iam];
+ size_type i = beg_partition[iam];
+ while (it!= access[iam+1])
+ {
+ r[i] = base_type::_M_create_node(*it);
+ ++i;
+ ++it;
+ }
+ }
+ return r;
}
- return r;
- }
/** @brief Allocation of an array of nodes and initialization of
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr*
- _M_sorted_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type n, thread_index_t& num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- // Ghost node at the end to avoid extra comparisons in nodes_initializer.
- _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1)));
- r[n] = NULL;
-
- // Dealing with repetitions (EFFICIENCY ISSUE).
- _Iterator access_copy[num_threads+1];
- for (int i = 0; i <= num_threads; ++i)
- access_copy[i] = access[i];
- // Allocate and initialize the nodes
-#pragma omp parallel num_threads(num_threads)
+ _Rb_tree_node_ptr*
+ _M_sorted_bulk_allocation_and_initialization(_Iterator* access,
+ size_type* beg_partition,
+ size_type* rank_shift,
+ const size_type n,
+ thread_index_t& num_threads,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
{
+ // Ghost node at the end to avoid extra comparisons
+ // in nodes_initializer.
+ _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>(
+ ::operator new(sizeof(_Rb_tree_node_ptr) * (n + 1)));
+ r[n] = NULL;
+
+ // Dealing with repetitions (EFFICIENCY ISSUE).
+ _Iterator access_copy[num_threads+1];
+ for (int i = 0; i <= num_threads; ++i)
+ access_copy[i] = access[i];
+ // Allocate and initialize the nodes
+#pragma omp parallel num_threads(num_threads)
+ {
#if USE_PAPI
- PAPI_register_thread();
+ PAPI_register_thread();
#endif
- thread_index_t iam = omp_get_thread_num();
- _Iterator prev = access[iam];
- size_type i = beg_partition[iam];
- _Iterator it = prev;
- if (iam != 0)
- {
- --prev;
- // Dealing with repetitions (CORRECTNESS ISSUE).
- while (it!= access_copy[iam+1] and not strictly_less_or_less_equal(_KeyOfValue()(*prev), _KeyOfValue()(*it)))
- {
- _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev)));
+ thread_index_t iam = omp_get_thread_num();
+ _Iterator prev = access[iam];
+ size_type i = beg_partition[iam];
+ _Iterator it = prev;
+ if (iam != 0)
+ {
+ --prev;
+ // Dealing with repetitions (CORRECTNESS ISSUE).
+ while (it!= access_copy[iam+1]
+ and not strictly_less_or_less_equal(_KeyOfValue()(*prev),
+ _KeyOfValue()(*it)))
+ {
+ _GLIBCXX_PARALLEL_ASSERT(not base_type::
+ _M_impl._M_key_compare
+ (_KeyOfValue()(*it),
+ _KeyOfValue()(*prev)));
+ ++it;
+ }
+ access[iam] = it;
+ if (it != access_copy[iam+1]){
+ r[i] = base_type::_M_create_node(*it);
+ ++i;
+ prev=it;
++it;
}
- access[iam] = it;
- if (it != access_copy[iam+1]){
- r[i] = base_type::_M_create_node(*it);
+ //}
+ }
+ else
+ {
+ r[i] = base_type::_M_create_node(*prev);
++i;
- prev=it;
++it;
}
- //}
- }
- else
- {
- r[i] = base_type::_M_create_node(*prev);
- ++i;
- ++it;
- }
- while (it!= access_copy[iam+1])
- {
+ while (it != access_copy[iam+1])
+ {
/***** Dealing with repetitions (CORRECTNESS ISSUE) *****/
- if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it)))
+ if (strictly_less_or_less_equal(_KeyOfValue()(*prev),
+ _KeyOfValue()(*it)))
{
r[i] = base_type::_M_create_node(*it);
++i;
prev=it;
}
- else{
- _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev)));
- }
+ else
+ _GLIBCXX_PARALLEL_ASSERT(not base_type::
+ _M_impl._M_key_compare
+ (_KeyOfValue()(*it),
+ _KeyOfValue()(*prev)));
++it;
}
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- rank_shift[iam+1] = beg_partition[iam+1] - i;
- }
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- rank_shift[0] = 0;
- /* Guarantee that there are no empty intervals.
- - If an empty interval is found, is joined with the previous one
- (the rank_shift of the previous is augmented with all the new
- repetitions)
- */
- thread_index_t i = 1;
- while (i <= num_threads and rank_shift[i] != (beg_partition[i] - beg_partition[i-1]))
- {
- rank_shift[i] += rank_shift[i-1];
- ++i;
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ rank_shift[iam+1] = beg_partition[iam+1] - i;
}
- if (i <= num_threads)
- {
- thread_index_t j = i - 1;
- while (true)
- {
- do
- {
- rank_shift[j] += rank_shift[i];
- ++i;
- } while (i <= num_threads and rank_shift[i] == (beg_partition[i] - beg_partition[i-1]));
-
- beg_partition[j] = beg_partition[i-1];
- access[j] = access[i-1];
- if (i > num_threads) break;
- ++j;
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ rank_shift[0] = 0;
+ /* Guarantee that there are no empty intervals.
+ - If an empty interval is found, is joined with the previous one
+ (the rank_shift of the previous is augmented with all the new
+ repetitions)
+ */
+ thread_index_t i = 1;
+ while (i <= num_threads
+ and rank_shift[i] != (beg_partition[i] - beg_partition[i-1]))
+ {
+ rank_shift[i] += rank_shift[i-1];
+ ++i;
+ }
+ if (i <= num_threads)
+ {
+ thread_index_t j = i - 1;
+ while (true)
+ {
+ do
+ {
+ rank_shift[j] += rank_shift[i];
+ ++i;
+ }
+ while (i <= num_threads
+ and rank_shift[i] == (beg_partition[i]
+ - beg_partition[i-1]));
- // Initialize with the previous.
- rank_shift[j] = rank_shift[j-1];
- }
- num_threads = j;
- }
- return r;
+ beg_partition[j] = beg_partition[i-1];
+ access[j] = access[i-1];
+ if (i > num_threads) break;
+ ++j;
+ // Initialize with the previous.
+ rank_shift[j] = rank_shift[j-1];
+ }
+ num_threads = j;
+ }
+ return r;
}
/** @brief Allocation of an array of nodes and initialization of
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr*
- _M_sorted_no_gapped_bulk_allocation_and_initialization(_Iterator* access, size_type* beg_partition, size_type& n, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- size_type* sums = static_cast<size_type*> (::operator new (sizeof(size_type)*n));
- // Allocate and initialize the nodes
- /* try
- {*/
-#pragma omp parallel num_threads(num_threads)
+ _Rb_tree_node_ptr*
+ _M_sorted_no_gapped_bulk_allocation_and_initialization
+ (_Iterator* access, size_type* beg_partition, size_type& n,
+ const thread_index_t num_threads,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
{
+ size_type* sums =
+ static_cast<size_type*>(::operator new (sizeof(size_type) * n));
+ // Allocate and initialize the nodes
+ /* try
+ {*/
+#pragma omp parallel num_threads(num_threads)
+ {
#if USE_PAPI
- PAPI_register_thread();
+ PAPI_register_thread();
#endif
- int iam = omp_get_thread_num();
- _Iterator prev = access[iam];
- size_type i = beg_partition[iam];
- _Iterator it = prev;
- if (iam !=0)
- {
- --prev;
+ int iam = omp_get_thread_num();
+ _Iterator prev = access[iam];
+ size_type i = beg_partition[iam];
+ _Iterator it = prev;
+ if (iam !=0)
+ {
+ --prev;
- // First iteration here, to update accessor in case was
- // equal to the last element of the previous range
+ // First iteration here, to update accessor in case was
+ // equal to the last element of the previous range
- // Dealing with repetitions (CORRECTNESS ISSUE).
- if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it)))
- {
- sums[i] = 0;
- prev=it;
- }
- else
- {
+ // Dealing with repetitions (CORRECTNESS ISSUE).
+ if (strictly_less_or_less_equal(_KeyOfValue()(*prev),
+ _KeyOfValue()(*it)))
+ {
+ sums[i] = 0;
+ prev=it;
+ }
+ else
sums[i] = 1;
- }
- ++i;
- ++it;
- }
+ ++i;
+ ++it;
+ }
else
{
sums[i] = 0;
while (it!= access[iam+1])
{
// Dealing with repetitions (CORRECTNESS ISSUE).
- if (strictly_less_or_less_equal(_KeyOfValue()(*prev),_KeyOfValue()(*it)))
+ if (strictly_less_or_less_equal(_KeyOfValue()(*prev),
+ _KeyOfValue()(*it)))
{
sums[i] = 0;
prev=it;
partial_sum(sums,sums + n, sums);
n -= sums[n-1];
- _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*> (::operator new (sizeof(_Rb_tree_node_ptr)*(n+1)));
+ _Rb_tree_node_ptr* r = static_cast<_Rb_tree_node_ptr*>(
+ ::operator new(sizeof(_Rb_tree_node_ptr) * (n + 1)));
r[n]=0;
#pragma omp parallel num_threads(num_threads)
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- void
- _M_sorted_bulk_construction(_Iterator* access, size_type* beg_partition, const size_type n, thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- // Dealing with repetitions (EFFICIENCY ISSUE).
- size_type rank_shift[num_threads+1];
-
- _Rb_tree_node_ptr* r = _M_sorted_bulk_allocation_and_initialization(access, beg_partition, rank_shift, n, num_threads, strictly_less_or_less_equal);
+ void
+ _M_sorted_bulk_construction(_Iterator* access, size_type* beg_partition,
+ const size_type n,
+ thread_index_t num_threads,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ // Dealing with repetitions (EFFICIENCY ISSUE).
+ size_type rank_shift[num_threads+1];
- // Link the tree appropriately.
- // Dealing with repetitions (EFFICIENCY ISSUE).
- ranker_gaps rank(beg_partition, rank_shift, num_threads);
- nodes_initializer<ranker_gaps> nodes_init(r, n - rank_shift[num_threads], num_threads, rank);
- size_type split = nodes_init.get_shifted_splitting_point();
+ _Rb_tree_node_ptr* r = _M_sorted_bulk_allocation_and_initialization
+ (access, beg_partition, rank_shift, n, num_threads,
+ strictly_less_or_less_equal);
+
+ // Link the tree appropriately.
+ // Dealing with repetitions (EFFICIENCY ISSUE).
+ ranker_gaps rank(beg_partition, rank_shift, num_threads);
+ nodes_initializer<ranker_gaps>
+ nodes_init(r, n - rank_shift[num_threads], num_threads, rank);
+ size_type split = nodes_init.get_shifted_splitting_point();
#pragma omp parallel num_threads(num_threads)
- {
+ {
#if USE_PAPI
- PAPI_register_thread();
+ PAPI_register_thread();
#endif
- int iam = omp_get_thread_num();
- size_type beg = beg_partition[iam];
- // Dealing with repetitions (EFFICIENCY ISSUE).
- size_type end = beg_partition[iam+1] - (rank_shift[iam+1] - rank_shift[iam]);
- if (split >= end)
- {
- for (size_type i = beg; i < end; ++i)
- {
+ int iam = omp_get_thread_num();
+ size_type beg = beg_partition[iam];
+ // Dealing with repetitions (EFFICIENCY ISSUE).
+ size_type end = (beg_partition[iam+1]
+ - (rank_shift[iam+1] - rank_shift[iam]));
+ if (split >= end)
+ {
+ for (size_type i = beg; i < end; ++i)
nodes_init.link_complete(r[i],iam);
- }
- }
- else
- {
- if (split <= beg)
- {
- for (size_type i = beg; i < end; ++i)
- nodes_init.link_incomplete(r[i],iam);
- }
- else
- {
- for (size_type i = beg; i < split; ++i)
- nodes_init.link_complete(r[i],iam);
- for (size_type i = split; i < end; ++i)
- nodes_init.link_incomplete(r[i],iam);
- }
- }
- }
- // If the execution reaches this point, there has been no
- // exception, and so the structure can be initialized.
-
- // Join the tree laid on the array of ptrs with the header node.
- // Dealing with repetitions (EFFICIENCY ISSUE).
- base_type::_M_impl._M_node_count = n - rank_shift[num_threads];
- base_type::_M_impl._M_header._M_left = r[0];
- thread_index_t with_element = num_threads;
- while ((beg_partition[with_element] - beg_partition[with_element-1]) == (rank_shift[with_element] - rank_shift[with_element-1]))
- {
- --with_element;
+ }
+ else
+ {
+ if (split <= beg)
+ {
+ for (size_type i = beg; i < end; ++i)
+ nodes_init.link_incomplete(r[i],iam);
+ }
+ else
+ {
+ for (size_type i = beg; i < split; ++i)
+ nodes_init.link_complete(r[i],iam);
+ for (size_type i = split; i < end; ++i)
+ nodes_init.link_incomplete(r[i],iam);
+ }
+ }
}
- base_type::_M_impl._M_header._M_right = r[beg_partition[with_element] - (rank_shift[with_element] - rank_shift[with_element-1]) - 1];
- base_type::_M_impl._M_header._M_parent = nodes_init.get_root();
- nodes_init.get_root()->_M_parent= &base_type::_M_impl._M_header;
+ // If the execution reaches this point, there has been no
+ // exception, and so the structure can be initialized.
- ::operator delete(r);
- }
+ // Join the tree laid on the array of ptrs with the header node.
+ // Dealing with repetitions (EFFICIENCY ISSUE).
+ base_type::_M_impl._M_node_count = n - rank_shift[num_threads];
+ base_type::_M_impl._M_header._M_left = r[0];
+ thread_index_t with_element = num_threads;
+ while ((beg_partition[with_element]
+ - beg_partition[with_element-1])
+ == (rank_shift[with_element] - rank_shift[with_element-1]))
+ --with_element;
+
+ base_type::_M_impl._M_header._M_right =
+ r[beg_partition[with_element]
+ - (rank_shift[with_element] - rank_shift[with_element-1]) - 1];
+ base_type::_M_impl._M_header._M_parent = nodes_init.get_root();
+ nodes_init.get_root()->_M_parent= &base_type::_M_impl._M_header;
+
+ ::operator delete(r);
+ }
/** @brief Main bulk insertion method: perform the actual
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- void
- _M_sorted_bulk_insertion(_Iterator* access, size_type* beg_partition, size_type k, thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- _GLIBCXX_PARALLEL_ASSERT((size_type)num_threads <= k);
- // num_thr-1 problems in the upper part of the tree
- // num_thr problems to further parallelize
- std::vector<size_type> existing(num_threads,0);
+ void
+ _M_sorted_bulk_insertion(_Iterator* access, size_type* beg_partition,
+ size_type k, thread_index_t num_threads,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ _GLIBCXX_PARALLEL_ASSERT((size_type)num_threads <= k);
+ // num_thr-1 problems in the upper part of the tree
+ // num_thr problems to further parallelize
+ std::vector<size_type> existing(num_threads,0);
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- size_type rank_shift[num_threads+1];
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ size_type rank_shift[num_threads+1];
- // Need to create them dynamically because they are so erased
- concat_problem* conc[2*num_threads-1];
+ // Need to create them dynamically because they are so erased
+ concat_problem* conc[2*num_threads-1];
#endif
- _Rb_tree_node_ptr* r;
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- if (not strictly_less_or_less_equal(base_type::_S_key(base_type::_M_root()),base_type::_S_key(base_type::_M_root()) ))
- {
- // Unique container
- // Set 1 and 2 could be done in parallel ...
- // 1. Construct the nodes with their corresponding data
+ _Rb_tree_node_ptr* r;
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ if (not strictly_less_or_less_equal
+ (base_type::_S_key(base_type::_M_root()),
+ base_type::_S_key(base_type::_M_root()) ))
+ {
+ // Unique container
+ // Set 1 and 2 could be done in parallel ...
+ // 1. Construct the nodes with their corresponding data
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- r = _M_sorted_bulk_allocation_and_initialization(access, beg_partition, rank_shift, k, num_threads, strictly_less_or_less_equal);
+ r = _M_sorted_bulk_allocation_and_initialization
+ (access, beg_partition, rank_shift, k, num_threads,
+ strictly_less_or_less_equal);
#else
- r = _M_sorted_no_gapped_bulk_allocation_and_initialization(access, beg_partition, k, num_threads, strictly_less_or_less_equal);
+ r = _M_sorted_no_gapped_bulk_allocation_and_initialization
+ (access, beg_partition, k, num_threads,
+ strictly_less_or_less_equal);
#endif
- }
- else
- {
- // Not unique container.
- r = _M_unsorted_bulk_allocation_and_initialization(access, beg_partition, k, num_threads);
+ }
+ else
+ {
+ // Not unique container.
+ r = _M_unsorted_bulk_allocation_and_initialization
+ (access, beg_partition, k, num_threads);
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- // Trivial initialization of rank_shift.
- for (int i=0; i <= num_threads; ++i)
- rank_shift[i] = 0;
+ // Trivial initialization of rank_shift.
+ for (int i=0; i <= num_threads; ++i)
+ rank_shift[i] = 0;
#endif
- }
+ }
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- // Calculate position of last element to be inserted: must be
- // done now, or otherwise becomes messy.
-
- /***** Dealing with
- repetitions (EFFICIENCY ISSUE) *****/
- size_type last = beg_partition[num_threads] - (rank_shift[num_threads] - rank_shift[num_threads - 1]);
-
- //2. Split the tree according to access in num_threads parts
- //Initialize upper concat_problems
- //Allocate them dynamically because they are afterwards so erased
- for (int i=0; i < (2*num_threads-1); ++i)
- {
+ // Calculate position of last element to be inserted: must be
+ // done now, or otherwise becomes messy.
+
+ /***** Dealing with
+ repetitions (EFFICIENCY ISSUE) *****/
+ size_type last = (beg_partition[num_threads]
+ - (rank_shift[num_threads]
+ - rank_shift[num_threads - 1]));
+
+ //2. Split the tree according to access in num_threads parts
+ //Initialize upper concat_problems
+ //Allocate them dynamically because they are afterwards so erased
+ for (int i=0; i < (2*num_threads-1); ++i)
conc[i] = new concat_problem ();
- }
- concat_problem* root_problem = _M_bulk_insertion_initialize_upper_problems(conc, 0, num_threads, NULL);
-
- // The first position of access and the last are ignored, so we
- // have exactly num_threads subtrees.
- bool before = omp_get_nested();
- omp_set_nested(true);
- _M_bulk_insertion_split_tree_by_pivot(static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), r, access, beg_partition, rank_shift, 0, num_threads-1, conc, num_threads, strictly_less_or_less_equal);
- omp_set_nested(before);
-
- // Construct upper tree with the first elements of ranges if
- // they are NULL We cannot do this by default because they could
- // be repeated and would not be checked.
- size_type r_s = 0;
- for (int pos = 1; pos < num_threads; ++pos)
- {
- _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or conc[pos*2-1]->t == NULL or strictly_less_or_less_equal(base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)), base_type::_S_key(conc[pos*2-1]->t)));
- _GLIBCXX_PARALLEL_ASSERT(conc[pos*2]->t == NULL or conc[pos*2-1]->t == NULL or strictly_less_or_less_equal( base_type::_S_key(conc[pos*2-1]->t), base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t))));
- /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/
+ concat_problem* root_problem =
+ _M_bulk_insertion_initialize_upper_problems(conc, 0,
+ num_threads, NULL);
+
+ // The first position of access and the last are ignored, so we
+ // have exactly num_threads subtrees.
+ bool before = omp_get_nested();
+ omp_set_nested(true);
+
+ _M_bulk_insertion_split_tree_by_pivot(
+ static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), r,
+ access, beg_partition, rank_shift, 0, num_threads - 1, conc,
+ num_threads, strictly_less_or_less_equal);
+
+ omp_set_nested(before);
+
+ // Construct upper tree with the first elements of ranges if
+ // they are NULL We cannot do this by default because they could
+ // be repeated and would not be checked.
+ size_type r_s = 0;
+ for (int pos = 1; pos < num_threads; ++pos)
+ {
+ _GLIBCXX_PARALLEL_ASSERT(
+ conc[(pos-1)*2]->t == NULL or conc[pos*2-1]->t == NULL
+ or strictly_less_or_less_equal
+ (base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)),
+ base_type::_S_key(conc[pos*2-1]->t)));
+ _GLIBCXX_PARALLEL_ASSERT(
+ conc[pos*2]->t == NULL or conc[pos*2-1]->t == NULL
+ or strictly_less_or_less_equal(
+ base_type::_S_key(conc[pos*2-1]->t),
+ base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t))));
+ /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/
- // The first element of the range is the root.
- if (conc[pos*2-1]->t == NULL or (not(strictly_less_or_less_equal(base_type::_S_key(static_cast<_Rb_tree_node_ptr>(conc[pos*2-1]->t)), _KeyOfValue()(*access[pos])))))
- {
- // There was not a candidate element
- // or
- // Exists an initialized position in the array which
- // corresponds to conc[pos*2-1]->t */
- if (conc[pos*2-1]->t == NULL)
- {
- size_t np = beg_partition[pos];
- _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or strictly_less_or_less_equal(base_type::_S_key(base_type::_S_maximum(conc[(pos-1)*2]->t)), base_type::_S_key(r[np])));
- _GLIBCXX_PARALLEL_ASSERT(conc[pos*2]->t == NULL or strictly_less_or_less_equal( base_type::_S_key(r[np]), base_type::_S_key(base_type::_S_minimum(conc[pos*2]->t))));
- conc[pos*2-1]->t = r[np];
- r[np]->_M_color = std::_S_black;
- ++base_type::_M_impl._M_node_count;
- }
- else
- {
+ // The first element of the range is the root.
+ if (conc[pos*2-1]->t == NULL
+ or (not(strictly_less_or_less_equal(
+ base_type::_S_key(static_cast<_Rb_tree_node_ptr>
+ (conc[pos*2-1]->t)),
+ _KeyOfValue()(*access[pos])))))
+ {
+ // There was not a candidate element
+ // or
+ // Exists an initialized position in the array which
+ // corresponds to conc[pos*2-1]->t */
+ if (conc[pos*2-1]->t == NULL)
+ {
+ size_t np = beg_partition[pos];
+ _GLIBCXX_PARALLEL_ASSERT(
+ conc[(pos-1)*2]->t == NULL
+ or strictly_less_or_less_equal
+ (base_type::_S_key(base_type::
+ _S_maximum(conc[(pos-1)*2]->t)),
+ base_type::_S_key(r[np])));
+ _GLIBCXX_PARALLEL_ASSERT(
+ conc[pos*2]->t == NULL
+ or strictly_less_or_less_equal(
+ base_type::_S_key(r[np]),
+ base_type::_S_key(base_type::
+ _S_minimum(conc[pos*2]->t))));
+ conc[pos*2-1]->t = r[np];
+ r[np]->_M_color = std::_S_black;
+ ++base_type::_M_impl._M_node_count;
+ }
+ else
base_type::_M_destroy_node(r[beg_partition[pos]]);
- }
- ++(access[pos]);
- ++(beg_partition[pos]);
- ++r_s;
- }
- _GLIBCXX_PARALLEL_ASSERT(conc[(pos-1)*2]->t == NULL or conc[(pos-1)*2]->t->_M_color == std::_S_black);
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- rank_shift[pos] += r_s;
- }
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- rank_shift[num_threads] += r_s;
+ ++(access[pos]);
+ ++(beg_partition[pos]);
+ ++r_s;
+ }
+ _GLIBCXX_PARALLEL_ASSERT(
+ conc[(pos-1)*2]->t == NULL
+ or conc[(pos-1)*2]->t->_M_color == std::_S_black);
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ rank_shift[pos] += r_s;
+ }
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ rank_shift[num_threads] += r_s;
#else
- concat_problem root_problem_on_stack(static_cast<_Rb_tree_node_ptr>(base_type::_M_root()), black_height(static_cast<_Rb_tree_node_ptr>(base_type::_M_root())), NULL);
- concat_problem * root_problem = &root_problem_on_stack;
- size_type last = k;
+ concat_problem root_problem_on_stack(
+ static_cast<_Rb_tree_node_ptr>(base_type::_M_root()),
+ black_height(static_cast<_Rb_tree_node_ptr>(base_type::_M_root())),
+ NULL);
+ concat_problem * root_problem = &root_problem_on_stack;
+ size_type last = k;
#endif
- // 3. Split the range according to tree and create
- // 3. insertion/concatenation problems to be solved in parallel
+ // 3. Split the range according to tree and create
+ // 3. insertion/concatenation problems to be solved in parallel
#if _GLIBCXX_TREE_DYNAMIC_BALANCING
- size_type min_problem = (k/num_threads) / (log2(k/num_threads + 1)+1);
+ size_type min_problem = (k/num_threads) / (log2(k/num_threads + 1)+1);
#else
- size_type min_problem = base_type::size() + k;
+ size_type min_problem = base_type::size() + k;
#endif
- RestrictedBoundedConcurrentQueue<insertion_problem>* ins_problems[num_threads];
+ RestrictedBoundedConcurrentQueue<insertion_problem>*
+ ins_problems[num_threads];
#pragma omp parallel num_threads(num_threads)
- {
- int num_thread = omp_get_thread_num();
- ins_problems[num_thread] = new RestrictedBoundedConcurrentQueue<insertion_problem>(2*(log2(base_type::size())+1));
+ {
+ int num_thread = omp_get_thread_num();
+ ins_problems[num_thread] =
+ new RestrictedBoundedConcurrentQueue<insertion_problem>
+ (2 * (log2(base_type::size()) + 1));
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- size_type end_k_thread = beg_partition[num_thread+1] - (rank_shift[num_thread+1] - rank_shift[num_thread]);
- ins_problems[num_thread]->push_front(insertion_problem(beg_partition[num_thread], end_k_thread, num_thread, conc[num_thread*2]));
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ size_type end_k_thread = (beg_partition[num_thread+1]
+ - (rank_shift[num_thread+1]
+ - rank_shift[num_thread]));
+ ins_problems[num_thread]->push_front(
+ insertion_problem(beg_partition[num_thread], end_k_thread,
+ num_thread, conc[num_thread*2]));
#else
- // size_type end_k_thread = beg_partition[num_thread+1];
+ // size_type end_k_thread = beg_partition[num_thread+1];
#endif
- insertion_problem ip_to_solve;
- bool change;
+ insertion_problem ip_to_solve;
+ bool change;
#if _GLIBCXX_TREE_INITIAL_SPLITTING
#pragma omp barrier
#else
#pragma omp single
- ins_problems[num_thread]->push_front(insertion_problem(0, k, num_thread, root_problem));
+ ins_problems[num_thread]->push_front(insertion_problem(
+ 0, k, num_thread,
+ root_problem));
#endif
- do
- {
- // First do own work.
- while (ins_problems[num_thread]->pop_front(ip_to_solve))
- {
- _GLIBCXX_PARALLEL_ASSERT(ip_to_solve.pos_beg <= ip_to_solve.pos_end);
- _M_bulk_insertion_split_sequence(r, ins_problems[num_thread], ip_to_solve, existing[num_thread], min_problem, strictly_less_or_less_equal);
-
- }
- yield();
- change = false;
+ do
+ {
+ // First do own work.
+ while (ins_problems[num_thread]->pop_front(ip_to_solve))
+ {
+ _GLIBCXX_PARALLEL_ASSERT(ip_to_solve.pos_beg
+ <= ip_to_solve.pos_end);
+ _M_bulk_insertion_split_sequence(
+ r, ins_problems[num_thread], ip_to_solve,
+ existing[num_thread], min_problem,
+ strictly_less_or_less_equal);
- //Then, try to steal from others (and become own).
- for (int i=1; i<num_threads; ++i)
- {
- if (ins_problems[(num_thread+i)%num_threads]->pop_back(ip_to_solve))
- {
- change = true;
- _M_bulk_insertion_split_sequence(r, ins_problems[num_thread], ip_to_solve, existing[num_thread], min_problem, strictly_less_or_less_equal);
- break;
- }
- }
- } while (change);
- }
+ }
+ yield();
+ change = false;
- // Update root and sizes.
- base_type::_M_root() = root_problem->t;
- root_problem->t->_M_parent = &(base_type::_M_impl._M_header);
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ //Then, try to steal from others (and become own).
+ for (int i=1; i<num_threads; ++i)
+ {
+ if (ins_problems[(num_thread + i)
+ % num_threads]->pop_back(ip_to_solve))
+ {
+ change = true;
+ _M_bulk_insertion_split_sequence(
+ r, ins_problems[num_thread], ip_to_solve,
+ existing[num_thread], min_problem,
+ strictly_less_or_less_equal);
+ break;
+ }
+ }
+ } while (change);
+ }
- // Add the k elements that wanted to be inserted, minus the ones
- // that were repeated.
+ // Update root and sizes.
+ base_type::_M_root() = root_problem->t;
+ root_problem->t->_M_parent = &(base_type::_M_impl._M_header);
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+
+ // Add the k elements that wanted to be inserted, minus the ones
+ // that were repeated.
#if _GLIBCXX_TREE_INITIAL_SPLITTING
- base_type::_M_impl._M_node_count += (k - (rank_shift[num_threads]));
+ base_type::_M_impl._M_node_count += (k - (rank_shift[num_threads]));
#else
- base_type::_M_impl._M_node_count += k;
+ base_type::_M_impl._M_node_count += k;
#endif
- // Also then, take out the ones that were already existing in the tree.
- for (int i = 0; i< num_threads; ++i)
- {
+ // Also then, take out the ones that were already existing in the tree.
+ for (int i = 0; i< num_threads; ++i)
base_type::_M_impl._M_node_count -= existing[i];
- }
- // Update leftmost and rightmost.
- /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
- if (not strictly_less_or_less_equal(base_type::_S_key(base_type::_M_root()), base_type::_S_key(base_type::_M_root()))){
- // Unique container.
- if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*(access[0])), base_type::_S_key(base_type::_M_leftmost())))
- base_type::_M_leftmost() = r[0];
- if (base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_M_rightmost()), _KeyOfValue()(*(--access[num_threads]))))
- base_type::_M_rightmost() = r[last - 1];
- }
- else{
- if (strictly_less_or_less_equal(_KeyOfValue()(*(access[0])), base_type::_S_key(base_type::_M_leftmost())))
- base_type::_M_leftmost() = base_type::_S_minimum(base_type::_M_root());
- if (strictly_less_or_less_equal(base_type::_S_key(base_type::_M_rightmost()), _KeyOfValue()(*(--access[num_threads]))))
- base_type::_M_rightmost() = base_type::_S_maximum(base_type::_M_root());
- }
-
-
-
+ // Update leftmost and rightmost.
+ /***** Dealing with repetitions (EFFICIENCY ISSUE) *****/
+ if (not strictly_less_or_less_equal(
+ base_type::_S_key(base_type::_M_root()),
+ base_type::_S_key(base_type::_M_root())))
+ {
+ // Unique container.
+ if (base_type::_M_impl._M_key_compare(
+ _KeyOfValue()(*(access[0])),
+ base_type::_S_key(base_type::_M_leftmost())))
+ base_type::_M_leftmost() = r[0];
+ if (base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_M_rightmost()),
+ _KeyOfValue()(*(--access[num_threads]))))
+ base_type::_M_rightmost() = r[last - 1];
+ }
+ else
+ {
+ if (strictly_less_or_less_equal(_KeyOfValue()(*(access[0])),
+ base_type::_S_key(base_type::
+ _M_leftmost())))
+ base_type::_M_leftmost() =
+ base_type::_S_minimum(base_type::_M_root());
+ if (strictly_less_or_less_equal(
+ base_type::_S_key(base_type::_M_rightmost()),
+ _KeyOfValue()(*(--access[num_threads]))))
+ base_type::_M_rightmost() =
+ base_type::_S_maximum(base_type::_M_root());
+ }
#if _GLIBCXX_TREE_INITIAL_SPLITTING
// Delete root problem
// Delete queues
for (int pos = 0; pos < num_threads; ++pos)
- {
- delete ins_problems[pos];
- }
+ delete ins_problems[pos];
// Delete array of pointers
::operator delete(r);
* of the wrapping container
*/
template<typename _Iterator, typename StrictlyLessOrLessEqual>
- void
- _M_bulk_insertion_split_tree_by_pivot(_Rb_tree_node_ptr t, _Rb_tree_node_ptr* r, _Iterator* access, size_type* beg_partition, size_type* rank_shift, const size_type pos_beg, const size_type pos_end, concat_problem** conc, const thread_index_t num_threads, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- if (pos_beg == pos_end)
- {
- //Elements are in [pos_beg, pos_end]
- conc[pos_beg*2]->t = t;
- conc[pos_beg*2]->black_h = black_height(t);
- force_black_root (conc[pos_beg*2]->t, conc[pos_beg*2]->black_h);
- return;
- }
- if (t == 0)
- {
- for (size_type i = pos_beg; i < pos_end; ++i)
- {
- conc[i*2]->t = NULL;
- conc[i*2]->black_h = 0;
- conc[i*2+1]->t = NULL;
- }
- conc[pos_end*2]->t = NULL;
- conc[pos_end*2]->black_h = 0;
- return;
- }
+ void
+ _M_bulk_insertion_split_tree_by_pivot(_Rb_tree_node_ptr t,
+ _Rb_tree_node_ptr* r,
+ _Iterator* access,
+ size_type* beg_partition,
+ size_type* rank_shift,
+ const size_type pos_beg,
+ const size_type pos_end,
+ concat_problem** conc,
+ const thread_index_t num_threads,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ if (pos_beg == pos_end)
+ {
+ //Elements are in [pos_beg, pos_end]
+ conc[pos_beg*2]->t = t;
+ conc[pos_beg*2]->black_h = black_height(t);
+ force_black_root (conc[pos_beg*2]->t, conc[pos_beg*2]->black_h);
+ return;
+ }
+ if (t == 0)
+ {
+ for (size_type i = pos_beg; i < pos_end; ++i)
+ {
+ conc[i*2]->t = NULL;
+ conc[i*2]->black_h = 0;
+ conc[i*2+1]->t = NULL;
+ }
+ conc[pos_end*2]->t = NULL;
+ conc[pos_end*2]->black_h = 0;
+ return;
+ }
- // Return the last pos, in which key >= (pos-1).
- // Search in the range [pos_beg, pos_end]
- size_type pos = std::upper_bound(access + pos_beg, access + pos_end + 1, base_type::_S_key(t), compare_value_key<_Iterator, _Compare>(base_type::_M_impl._M_key_compare)) - access;
- if (pos != pos_beg)
- {
+ // Return the last pos, in which key >= (pos-1).
+ // Search in the range [pos_beg, pos_end]
+ size_type pos = (std::upper_bound(access + pos_beg,
+ access + pos_end + 1,
+ base_type::_S_key(t),
+ compare_value_key<_Iterator,
+ _Compare>(base_type::
+ _M_impl._M_key_compare))
+ - access);
+ if (pos != pos_beg)
--pos;
- }
- _GLIBCXX_PARALLEL_ASSERT(pos == 0 or not base_type::_M_impl._M_key_compare(base_type::_S_key(t), _KeyOfValue()(*access[pos])));
-
-
- _Rb_tree_node_ptr ll, lr;
- int black_h_ll, black_h_lr;
- _Rb_tree_node_ptr rl, rr;
- int black_h_rl, black_h_rr;
-
- if (pos != pos_beg)
- {
- _Rb_tree_node_ptr prev = r[beg_partition[pos] - 1 - (rank_shift[pos] - rank_shift[pos - 1])];
-
- _GLIBCXX_PARALLEL_ASSERT(strictly_less_or_less_equal(base_type::_S_key(prev), _KeyOfValue()(*access[pos])));
- split(static_cast<_Rb_tree_node_ptr>(t->_M_left),
- static_cast<const key_type&>(_KeyOfValue()(*access[pos])),
- static_cast<const key_type&>(base_type::_S_key(prev)),
- conc[pos*2-1]->t, ll, lr, black_h_ll, black_h_lr,
- strictly_less_or_less_equal);
+ _GLIBCXX_PARALLEL_ASSERT(
+ pos == 0
+ or not base_type::_M_impl._M_key_compare(
+ base_type::_S_key(t), _KeyOfValue()(*access[pos])));
- _M_bulk_insertion_split_tree_by_pivot(ll, r, access, beg_partition, rank_shift, pos_beg, pos-1, conc,num_threads, strictly_less_or_less_equal);
- }
- else
- {
- lr = static_cast<_Rb_tree_node_ptr>(t->_M_left);
- black_h_lr = black_height (lr);
- force_black_root (lr, black_h_lr);
- }
-
- if (pos != pos_end)
- {
- _Rb_tree_node_ptr prev = r[beg_partition[pos+1] - 1 - (rank_shift[pos+1] - rank_shift[pos])];
+
+ _Rb_tree_node_ptr ll, lr;
+ int black_h_ll, black_h_lr;
+ _Rb_tree_node_ptr rl, rr;
+ int black_h_rl, black_h_rr;
- _GLIBCXX_PARALLEL_ASSERT(not base_type::_M_impl._M_key_compare(_KeyOfValue()(*access[pos+1]), base_type::_S_key(prev)));
- _GLIBCXX_PARALLEL_ASSERT(strictly_less_or_less_equal(base_type::_S_key(prev), _KeyOfValue()(*access[pos+1])));
-
- split(static_cast<_Rb_tree_node_ptr>(t->_M_right),
- static_cast<const key_type&>(_KeyOfValue()(*access[pos+1])),
- static_cast<const key_type&>(base_type::_S_key(prev)),
- conc[pos*2+1]->t, rl, rr, black_h_rl, black_h_rr,
- strictly_less_or_less_equal);
+ if (pos != pos_beg)
+ {
+ _Rb_tree_node_ptr prev = (r[beg_partition[pos] - 1
+ - (rank_shift[pos]
+ - rank_shift[pos - 1])]);
+
+ _GLIBCXX_PARALLEL_ASSERT(
+ strictly_less_or_less_equal(base_type::_S_key(prev),
+ _KeyOfValue()(*access[pos])));
+
+ split(static_cast<_Rb_tree_node_ptr>(t->_M_left),
+ static_cast<const key_type&>(_KeyOfValue()(*access[pos])),
+ static_cast<const key_type&>(base_type::_S_key(prev)),
+ conc[pos*2-1]->t, ll, lr, black_h_ll, black_h_lr,
+ strictly_less_or_less_equal);
+
+ _M_bulk_insertion_split_tree_by_pivot(
+ ll, r, access, beg_partition, rank_shift, pos_beg, pos-1,
+ conc, num_threads, strictly_less_or_less_equal);
+ }
+ else
+ {
+ lr = static_cast<_Rb_tree_node_ptr>(t->_M_left);
+ black_h_lr = black_height (lr);
+ force_black_root (lr, black_h_lr);
+ }
- _M_bulk_insertion_split_tree_by_pivot(rr, r, access, beg_partition, rank_shift, pos+1, pos_end, conc,num_threads, strictly_less_or_less_equal);
- }
- else
- {
- rl = static_cast<_Rb_tree_node_ptr>(t->_M_right);
- black_h_rl = black_height (rl);
- force_black_root (rl, black_h_rl);
- }
+ if (pos != pos_end)
+ {
+ _Rb_tree_node_ptr prev = (r[beg_partition[pos+1] - 1
+ - (rank_shift[pos+1]
+ - rank_shift[pos])]);
+
+ _GLIBCXX_PARALLEL_ASSERT(
+ not base_type::_M_impl._M_key_compare(
+ _KeyOfValue()(*access[pos+1]), base_type::_S_key(prev)));
+ _GLIBCXX_PARALLEL_ASSERT(
+ strictly_less_or_less_equal(base_type::_S_key(prev),
+ _KeyOfValue()(*access[pos+1])));
+
+ split(static_cast<_Rb_tree_node_ptr>(t->_M_right),
+ static_cast<const key_type&>(_KeyOfValue()(*access[pos+1])),
+ static_cast<const key_type&>(base_type::_S_key(prev)),
+ conc[pos*2+1]->t, rl, rr, black_h_rl, black_h_rr,
+ strictly_less_or_less_equal);
+
+ _M_bulk_insertion_split_tree_by_pivot(
+ rr, r, access, beg_partition, rank_shift, pos+1, pos_end,
+ conc,num_threads, strictly_less_or_less_equal);
+ }
+ else
+ {
+ rl = static_cast<_Rb_tree_node_ptr>(t->_M_right);
+ black_h_rl = black_height (rl);
+ force_black_root (rl, black_h_rl);
+ }
- // When key(t) is equal to key(access[pos]) and no other key in
- // the left tree satisfies the criteria to be conc[pos*2-1]->t,
- // key(t) must be assigned to it to avoid repetitions.
- // Therefore, we do not have a root parameter for the
- // concatenate function and a new concatenate function must be
- // provided.
- if (pos != pos_beg and conc[pos*2-1]->t == NULL and not strictly_less_or_less_equal(_KeyOfValue()(*access[pos]), base_type::_S_key(t)))
- {
- conc[pos*2-1]->t = t;
- t = NULL;
- }
- concatenate(t, lr, rl, black_h_lr, black_h_rl, conc[pos*2]->t, conc[pos*2]->black_h);
- }
+ // When key(t) is equal to key(access[pos]) and no other key in
+ // the left tree satisfies the criteria to be conc[pos*2-1]->t,
+ // key(t) must be assigned to it to avoid repetitions.
+ // Therefore, we do not have a root parameter for the
+ // concatenate function and a new concatenate function must be
+ // provided.
+ if (pos != pos_beg and conc[pos*2-1]->t == NULL
+ and not strictly_less_or_less_equal(_KeyOfValue()(*access[pos]),
+ base_type::_S_key(t)))
+ {
+ conc[pos*2-1]->t = t;
+ t = NULL;
+ }
+ concatenate(t, lr, rl, black_h_lr, black_h_rl,
+ conc[pos*2]->t, conc[pos*2]->black_h);
+ }
/** @brief Divide the insertion problem until a leaf is reached or
* the problem is small.
* of the wrapping container
*/
template<typename StrictlyLessOrLessEqual>
- void
- _M_bulk_insertion_split_sequence(_Rb_tree_node_ptr* r, RestrictedBoundedConcurrentQueue<insertion_problem>* ins_problems, insertion_problem& ip, size_type& existing, const size_type min_problem, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- _GLIBCXX_PARALLEL_ASSERT(ip.t == ip.conc->t);
- if (ip.t == NULL or (ip.pos_end- ip.pos_beg) <= min_problem)
- {
- // SOLVE PROBLEM SEQUENTIALLY
- // Start solving the problem.
- _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end);
- _M_bulk_insertion_merge_concatenate(r, ip, existing, strictly_less_or_less_equal);
- return;
- }
+ void
+ _M_bulk_insertion_split_sequence(
+ _Rb_tree_node_ptr* r,
+ RestrictedBoundedConcurrentQueue<insertion_problem>* ins_problems,
+ insertion_problem& ip, size_type& existing,
+ const size_type min_problem,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ {
+ _GLIBCXX_PARALLEL_ASSERT(ip.t == ip.conc->t);
+ if (ip.t == NULL or (ip.pos_end- ip.pos_beg) <= min_problem)
+ {
+ // SOLVE PROBLEM SEQUENTIALLY
+ // Start solving the problem.
+ _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end);
+ _M_bulk_insertion_merge_concatenate(r, ip, existing,
+ strictly_less_or_less_equal);
+ return;
+ }
- size_type pos_beg_right;
- size_type pos_end_left = divide(r, ip.pos_beg, ip.pos_end, base_type::_S_key(ip.t), pos_beg_right, existing, strictly_less_or_less_equal);
+ size_type pos_beg_right;
+ size_type pos_end_left = divide(r, ip.pos_beg, ip.pos_end,
+ base_type::_S_key(ip.t), pos_beg_right,
+ existing, strictly_less_or_less_equal);
- int black_h_l, black_h_r;
- if (ip.t->_M_color == std::_S_black)
- {
+ int black_h_l, black_h_r;
+ if (ip.t->_M_color == std::_S_black)
black_h_l = black_h_r = ip.conc->black_h - 1;
- }
- else
- {
+ else
black_h_l = black_h_r = ip.conc->black_h;
- }
// Right problem into the queue.
- ip.conc->right_problem = new concat_problem(static_cast<_Rb_tree_node_ptr>(ip.t->_M_right), black_h_r, ip.conc);
- ip.conc->left_problem = new concat_problem(static_cast<_Rb_tree_node_ptr>(ip.t->_M_left), black_h_l, ip.conc);
+ ip.conc->right_problem = new concat_problem(
+ static_cast<_Rb_tree_node_ptr>(ip.t->_M_right), black_h_r, ip.conc);
+ ip.conc->left_problem = new concat_problem(
+ static_cast<_Rb_tree_node_ptr>(ip.t->_M_left), black_h_l, ip.conc);
- ins_problems->push_front(insertion_problem(pos_beg_right, ip.pos_end, ip.array_partition, ip.conc->right_problem));
+ ins_problems->push_front(insertion_problem(pos_beg_right, ip.pos_end,
+ ip.array_partition,
+ ip.conc->right_problem));
// Solve left problem.
- insertion_problem ip_left(ip.pos_beg, pos_end_left, ip.array_partition, ip.conc->left_problem);
- _M_bulk_insertion_split_sequence(r, ins_problems, ip_left, existing, min_problem, strictly_less_or_less_equal);
+ insertion_problem ip_left(ip.pos_beg, pos_end_left, ip.array_partition,
+ ip.conc->left_problem);
+ _M_bulk_insertion_split_sequence(r, ins_problems, ip_left, existing,
+ min_problem,
+ strictly_less_or_less_equal);
}
* @return Resulting tree after the elements have been inserted
*/
template<typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr
- _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t, const size_type pos_beg, const size_type pos_end, size_type& existing, int& black_h, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
+ _Rb_tree_node_ptr
+ _M_bulk_insertion_merge(_Rb_tree_node_ptr* r_array, _Rb_tree_node_ptr t,
+ const size_type pos_beg,
+ const size_type pos_end,
+ size_type& existing, int& black_h,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
#ifndef NDEBUG
- int count;
+ int count;
#endif
- _GLIBCXX_PARALLEL_ASSERT(pos_beg<=pos_end);
+ _GLIBCXX_PARALLEL_ASSERT(pos_beg<=pos_end);
- // Leaf: a tree with the range must be constructed. Returns its
- // height in black nodes and its root (in ip.t) If there is
- // nothing to insert, we still need the height for balancing.
- if (t == NULL)
- {
- if (pos_end == pos_beg) return NULL;
- t = simple_tree_construct(r_array,pos_beg, pos_end, black_h);
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count));
- return t;
- }
- if (pos_end == pos_beg)
- return t;
- if ((pos_end - pos_beg) <= (size_type)(black_h))
- {
- // Exponential size tree with respect the number of elements
- // to be inserted.
- for (size_type p = pos_beg; p < pos_end; ++p)
- {
- t = _M_insert_local(t, r_array[p], existing, black_h, strictly_less_or_less_equal);
- }
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count));
+ // Leaf: a tree with the range must be constructed. Returns its
+ // height in black nodes and its root (in ip.t) If there is
+ // nothing to insert, we still need the height for balancing.
+ if (t == NULL)
+ {
+ if (pos_end == pos_beg)
+ return NULL;
+ t = simple_tree_construct(r_array,pos_beg, pos_end, black_h);
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count));
+ return t;
+ }
+ if (pos_end == pos_beg)
return t;
- }
-
- size_type pos_beg_right;
- size_type pos_end_left = divide(r_array, pos_beg, pos_end, base_type::_S_key(t), pos_beg_right, existing, strictly_less_or_less_equal);
+ if ((pos_end - pos_beg) <= (size_type)(black_h))
+ {
+ // Exponential size tree with respect the number of elements
+ // to be inserted.
+ for (size_type p = pos_beg; p < pos_end; ++p)
+ t = _M_insert_local(t, r_array[p], existing, black_h,
+ strictly_less_or_less_equal);
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(t,count));
+ return t;
+ }
+ size_type pos_beg_right;
+ size_type pos_end_left = divide(r_array, pos_beg, pos_end,
+ base_type::_S_key(t), pos_beg_right,
+ existing, strictly_less_or_less_equal);
- int black_h_l, black_h_r;
- if (t->_M_color == std::_S_black)
- {
+ int black_h_l, black_h_r;
+ if (t->_M_color == std::_S_black)
black_h_l = black_h_r = black_h - 1;
- }
- else
- {
+ else
black_h_l = black_h_r = black_h;
- }
- force_black_root(t->_M_left, black_h_l);
- _Rb_tree_node_ptr l = _M_bulk_insertion_merge(r_array, static_cast<_Rb_tree_node_ptr>(t->_M_left), pos_beg, pos_end_left, existing, black_h_l, strictly_less_or_less_equal);
- force_black_root(t->_M_right, black_h_r);
- _Rb_tree_node_ptr r = _M_bulk_insertion_merge(r_array, static_cast<_Rb_tree_node_ptr>(t->_M_right), pos_beg_right, pos_end, existing, black_h_r, strictly_less_or_less_equal);
+
+ force_black_root(t->_M_left, black_h_l);
- concatenate(t, l, r, black_h_l, black_h_r, t, black_h);
+ _Rb_tree_node_ptr l = _M_bulk_insertion_merge(
+ r_array, static_cast<_Rb_tree_node_ptr>(t->_M_left), pos_beg,
+ pos_end_left, existing, black_h_l, strictly_less_or_less_equal);
- return t;
- }
+ force_black_root(t->_M_right, black_h_r);
+
+ _Rb_tree_node_ptr r = _M_bulk_insertion_merge(
+ r_array, static_cast<_Rb_tree_node_ptr>(t->_M_right), pos_beg_right,
+ pos_end, existing, black_h_r, strictly_less_or_less_equal);
+
+ concatenate(t, l, r, black_h_l, black_h_r, t, black_h);
+
+ return t;
+ }
/** @brief Solve a given insertion problem and all the parent
* concatenation problem that are ready to be solved.
* of the wrapping container
*/
template<typename StrictlyLessOrLessEqual>
- void
- _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r, insertion_problem& ip, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- concat_problem* conc = ip.conc;
- _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end);
+ void
+ _M_bulk_insertion_merge_concatenate(_Rb_tree_node_ptr* r,
+ insertion_problem& ip,
+ size_type& existing,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal)
+ {
+ concat_problem* conc = ip.conc;
+ _GLIBCXX_PARALLEL_ASSERT(ip.pos_beg <= ip.pos_end);
- conc->t = _M_bulk_insertion_merge(r, ip.t, ip.pos_beg, ip.pos_end, existing, conc->black_h, strictly_less_or_less_equal);
- _GLIBCXX_PARALLEL_ASSERT(conc->t == NULL or conc->t->_M_color == std::_S_black);
+ conc->t = _M_bulk_insertion_merge(r, ip.t, ip.pos_beg, ip.pos_end,
+ existing, conc->black_h,
+ strictly_less_or_less_equal);
+ _GLIBCXX_PARALLEL_ASSERT(conc->t == NULL
+ or conc->t->_M_color == std::_S_black);
- bool is_ready = true;
- while (conc->par_problem != NULL and is_ready)
- {
- // Pre: exists left and right problem, so there is not a deadlock
- if (compare_and_swap(&conc->par_problem->is_ready, concat_problem::READY_NO, concat_problem::READY_YES))
- is_ready = false;
+ bool is_ready = true;
+ while (conc->par_problem != NULL and is_ready)
+ {
+ // Pre: exists left and right problem, so there is not a deadlock
+ if (compare_and_swap(&conc->par_problem->is_ready,
+ concat_problem::READY_NO,
+ concat_problem::READY_YES))
+ is_ready = false;
- if (is_ready)
- {
- conc = conc->par_problem;
- _GLIBCXX_PARALLEL_ASSERT(conc->left_problem!=NULL and conc->right_problem!=NULL);
- _GLIBCXX_PARALLEL_ASSERT (conc->left_problem->black_h >=0 and conc->right_problem->black_h>=0);
- // Finished working with the problems.
- concatenate(conc->t, conc->left_problem->t, conc->right_problem->t, conc->left_problem->black_h, conc->right_problem->black_h, conc->t, conc->black_h);
-
- delete conc->left_problem;
- delete conc->right_problem;
- }
- }
- }
+ if (is_ready)
+ {
+ conc = conc->par_problem;
+ _GLIBCXX_PARALLEL_ASSERT(conc->left_problem!=NULL
+ and conc->right_problem!=NULL);
+ _GLIBCXX_PARALLEL_ASSERT(conc->left_problem->black_h >=0
+ and conc->right_problem->black_h>=0);
+ // Finished working with the problems.
+ concatenate(conc->t, conc->left_problem->t,
+ conc->right_problem->t,
+ conc->left_problem->black_h,
+ conc->right_problem->black_h,
+ conc->t, conc->black_h);
+
+ delete conc->left_problem;
+ delete conc->right_problem;
+ }
+ }
+ }
// Begin of sorting, searching and related comparison-based helper methods.
* @param dist Size of the sequence (out)
* @return sequence is sorted. */
template<typename _RandomAccessIterator>
- bool
- is_sorted_distance(const _RandomAccessIterator __first, const _RandomAccessIterator __last, size_type& dist, std::random_access_iterator_tag) const
- {
- gr_or_eq<_Compare, _RandomAccessIterator> geq(base_type::_M_impl._M_key_compare);
- dist = __last - __first;
+ bool
+ is_sorted_distance(const _RandomAccessIterator __first,
+ const _RandomAccessIterator __last,
+ size_type& dist,
+ std::random_access_iterator_tag) const
+ {
+ gr_or_eq<_Compare, _RandomAccessIterator>
+ geq(base_type::_M_impl._M_key_compare);
+ dist = __last - __first;
- // In parallel.
- return equal(__first + 1, __last, __first, geq);
- }
+ // In parallel.
+ return equal(__first + 1, __last, __first, geq);
+ }
- /** @brief Check whether an input sequence is sorted, and
- * calculate its size.
- *
- * The list partitioning tool is used so that all the work is
- * done in only one traversal.
- * @param __first Begin iterator of sequence.
- * @param __last End iterator of sequence.
- * @param dist Size of the sequence (out)
- * @return sequence is sorted. */
- template<typename _InputIterator>
- bool
- is_sorted_distance(const _InputIterator __first, const _InputIterator __last, size_type& dist, std::input_iterator_tag) const
- {
- dist = 1;
- bool is_sorted = true;
- _InputIterator it = __first;
- _InputIterator prev = it++;
- while (it != __last)
- {
- ++dist;
- if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),_KeyOfValue()(*prev)))
- {
- is_sorted = false;
- ++it;
- break;
- }
- prev = it;
- ++it;
- }
- while (it != __last)
- {
- ++dist;
- ++it;
- }
- return is_sorted;
- }
+ /** @brief Check whether an input sequence is sorted, and
+ * calculate its size.
+ *
+ * The list partitioning tool is used so that all the work is
+ * done in only one traversal.
+ * @param __first Begin iterator of sequence.
+ * @param __last End iterator of sequence.
+ * @param dist Size of the sequence (out)
+ * @return sequence is sorted. */
+ template<typename _InputIterator>
+ bool
+ is_sorted_distance(const _InputIterator __first,
+ const _InputIterator __last, size_type& dist,
+ std::input_iterator_tag) const
+ {
+ dist = 1;
+ bool is_sorted = true;
+ _InputIterator it = __first;
+ _InputIterator prev = it++;
+ while (it != __last)
+ {
+ ++dist;
+ if (base_type::_M_impl._M_key_compare(_KeyOfValue()(*it),
+ _KeyOfValue()(*prev)))
+ {
+ is_sorted = false;
+ ++it;
+ break;
+ }
+ prev = it;
+ ++it;
+ }
+ while (it != __last)
+ {
+ ++dist;
+ ++it;
+ }
+ return is_sorted;
+ }
/** @brief Check whether a random-access sequence is sorted,
* calculate its size, and obtain intermediate accessors to the
* @param num_pieces Number of pieces to generate.
* @return Sequence is sorted. */
template<typename _RandomAccessIterator>
- bool
- is_sorted_distance_accessors(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _RandomAccessIterator* access, size_type* beg_partition, size_type& dist, thread_index_t& num_pieces, std::random_access_iterator_tag) const
- {
- bool is_sorted = is_sorted_distance(__first, __last, dist,std::__iterator_category(__first));
- if (dist < (unsigned int) num_pieces)
- num_pieces = dist;
-
- // Do it opposite way to use accessors in equal function???
- range_accessors(__first,__last, access, beg_partition, dist, num_pieces, std::__iterator_category(__first));
- return is_sorted;
- }
+ bool
+ is_sorted_distance_accessors(const _RandomAccessIterator __first,
+ const _RandomAccessIterator __last,
+ _RandomAccessIterator* access,
+ size_type* beg_partition, size_type& dist,
+ thread_index_t& num_pieces,
+ std::random_access_iterator_tag) const
+ {
+ bool is_sorted = is_sorted_distance(__first, __last, dist,
+ std::__iterator_category(__first));
+ if (dist < (unsigned int) num_pieces)
+ num_pieces = dist;
+
+ // Do it opposite way to use accessors in equal function???
+ range_accessors(__first,__last, access, beg_partition, dist,
+ num_pieces, std::__iterator_category(__first));
+ return is_sorted;
+ }
/** @brief Check whether an input sequence is sorted, calculate
* its size, and obtain intermediate accessors to the sequence to
* @param num_pieces Number of pieces to generate.
* @return Sequence is sorted. */
template<typename _InputIterator>
- bool
- is_sorted_distance_accessors(const _InputIterator __first, const _InputIterator __last, _InputIterator* access, size_type* beg_partition, size_type& dist, thread_index_t& num_pieces, std::input_iterator_tag) const
- {
- is_sorted_functor<_InputIterator, _Compare> sorted(__first, base_type::_M_impl._M_key_compare);
- dist = list_partition(__first, __last, access, (beg_partition+1), num_pieces, sorted, 0);
-
- // Calculate the rank of the beginning each partition from the
- // sequence sizes (what is stored at this point in beg_partition
- // array).
- beg_partition[0] = 0;
- for (int i = 0; i < num_pieces; ++i)
- {
+ bool
+ is_sorted_distance_accessors(const _InputIterator __first,
+ const _InputIterator __last,
+ _InputIterator* access,
+ size_type* beg_partition, size_type& dist,
+ thread_index_t& num_pieces,
+ std::input_iterator_tag) const
+ {
+ is_sorted_functor<_InputIterator, _Compare>
+ sorted(__first, base_type::_M_impl._M_key_compare);
+ dist = list_partition(__first, __last, access, (beg_partition+1),
+ num_pieces, sorted, 0);
+
+ // Calculate the rank of the beginning each partition from the
+ // sequence sizes (what is stored at this point in beg_partition
+ // array).
+ beg_partition[0] = 0;
+ for (int i = 0; i < num_pieces; ++i)
beg_partition[i+1] += beg_partition[i];
- }
- return sorted.is_sorted();
- }
+ return sorted.is_sorted();
+ }
/** @brief Make a full copy of the elements of a sequence
*
* @param out Begin iterator of output sequence.
* @param num_threads Number of threads to use. */
template<typename _InputIterator, typename _OutputIterator>
- static void
- uninitialized_copy_from_accessors(_InputIterator* access, size_type* beg_partition, _OutputIterator out, const thread_index_t num_threads)
- {
-#pragma omp parallel num_threads(num_threads)
+ static void
+ uninitialized_copy_from_accessors(_InputIterator* access,
+ size_type* beg_partition,
+ _OutputIterator out,
+ const thread_index_t num_threads)
{
- int iam = omp_get_thread_num();
- uninitialized_copy(access[iam], access[iam+1], out+beg_partition[iam]);
+#pragma omp parallel num_threads(num_threads)
+ {
+ int iam = omp_get_thread_num();
+ uninitialized_copy(access[iam], access[iam + 1],
+ out + beg_partition[iam]);
+ }
}
- }
/** @brief Make a copy of the pointers of the elements of a sequence
* @param access Array of size @c num_threads + 1 that defines @c
* @param out Begin iterator of output sequence.
* @param num_threads Number of threads to use. */
template<typename _InputIterator, typename _OutputIterator>
- static void
- uninitialized_ptr_copy_from_accessors(_InputIterator* access, size_type* beg_partition, _OutputIterator out, const thread_index_t num_threads)
- {
-#pragma omp parallel num_threads(num_threads)
+ static void
+ uninitialized_ptr_copy_from_accessors(_InputIterator* access,
+ size_type* beg_partition,
+ _OutputIterator out,
+ const thread_index_t num_threads)
{
- int iam = omp_get_thread_num();
- _OutputIterator itout = out + beg_partition[iam];
- for (_InputIterator it = access[iam]; it != access[iam+1]; ++it)
- {
- *itout = &(*it);
- ++itout;
- }
+#pragma omp parallel num_threads(num_threads)
+ {
+ int iam = omp_get_thread_num();
+ _OutputIterator itout = out + beg_partition[iam];
+ for (_InputIterator it = access[iam]; it != access[iam+1]; ++it)
+ {
+ *itout = &(*it);
+ ++itout;
+ }
+ }
}
- }
/** @brief Split a sorted node array in two parts according to a key.
*
* resulting left partition (out)
*/
template<typename StrictlyLessOrLessEqual>
- size_type
- divide(_Rb_tree_node_ptr* r, const size_type pos_beg, const size_type pos_end, const key_type& key, size_type& pos_beg_right, size_type& existing, StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- pos_beg_right = std::lower_bound(r + pos_beg, r + pos_end, key, compare_node_key<_Compare>(base_type::_M_impl._M_key_compare)) - r;
-
- //Check if the element exists.
- size_type pos_end_left = pos_beg_right;
-
- // If r[pos_beg_right] is equal to key, must be erased
- /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/
- _GLIBCXX_PARALLEL_ASSERT((pos_beg_right == pos_end) or not base_type::_M_impl._M_key_compare(base_type::_S_key(r[pos_beg_right]),key));
- _GLIBCXX_PARALLEL_ASSERT((pos_beg_right + 1 >= pos_end) or strictly_less_or_less_equal(key, base_type::_S_key(r[pos_beg_right + 1])));
- if (pos_beg_right != pos_end and not strictly_less_or_less_equal(key, base_type::_S_key(r[pos_beg_right])))
- {
- _M_destroy_node(r[pos_beg_right]);
- r[pos_beg_right] = NULL;
- ++pos_beg_right;
- ++existing;
- }
- _GLIBCXX_PARALLEL_ASSERT(pos_end_left <= pos_beg_right and pos_beg_right <= pos_end and pos_end_left >= pos_beg);
- return pos_end_left;
- }
+ size_type
+ divide(_Rb_tree_node_ptr* r, const size_type pos_beg,
+ const size_type pos_end, const key_type& key,
+ size_type& pos_beg_right, size_type& existing,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ {
+ pos_beg_right = std::lower_bound(
+ r + pos_beg, r + pos_end, key, compare_node_key<_Compare>(
+ base_type::_M_impl._M_key_compare)) - r;
+
+ //Check if the element exists.
+ size_type pos_end_left = pos_beg_right;
+
+ // If r[pos_beg_right] is equal to key, must be erased
+ /***** Dealing with repetitions (CORRECTNESS ISSUE) *****/
+ _GLIBCXX_PARALLEL_ASSERT(
+ (pos_beg_right == pos_end)
+ or not base_type::_M_impl._M_key_compare(
+ base_type::_S_key(r[pos_beg_right]),key));
+ _GLIBCXX_PARALLEL_ASSERT(
+ (pos_beg_right + 1 >= pos_end)
+ or strictly_less_or_less_equal(
+ key, base_type::_S_key(r[pos_beg_right + 1])));
+
+ if (pos_beg_right != pos_end
+ and not strictly_less_or_less_equal(
+ key, base_type::_S_key(r[pos_beg_right])))
+ {
+ _M_destroy_node(r[pos_beg_right]);
+ r[pos_beg_right] = NULL;
+ ++pos_beg_right;
+ ++existing;
+ }
+ _GLIBCXX_PARALLEL_ASSERT(pos_end_left <= pos_beg_right
+ and pos_beg_right <= pos_end
+ and pos_end_left >= pos_beg);
+ return pos_end_left;
+ }
/** @brief Parallelization helper method: Given a random-access
* @param n Sequence size
* @param num_pieces Number of pieces. */
template<typename _RandomAccessIterator>
- static void
- range_accessors(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _RandomAccessIterator* access, size_type* beg_partition, const size_type n, const thread_index_t num_pieces, std::random_access_iterator_tag)
- {
- access[0] = __first;
- for (int i=1; i< num_pieces; ++i)
- {
- access[i] = access[i-1] + (__last-__first)/num_pieces;
- beg_partition[i]= beg_partition[i-1]+ (__last-__first)/num_pieces;
- }
- beg_partition[num_pieces] = __last - access[num_pieces-1] + beg_partition[num_pieces-1];
- access[num_pieces]= __last;
- }
+ static void
+ range_accessors(const _RandomAccessIterator __first,
+ const _RandomAccessIterator __last,
+ _RandomAccessIterator* access,
+ size_type* beg_partition,
+ const size_type n,
+ const thread_index_t num_pieces,
+ std::random_access_iterator_tag)
+ {
+ access[0] = __first;
+ for (int i = 1; i< num_pieces; ++i)
+ {
+ access[i] = access[i-1] + (__last-__first)/num_pieces;
+ beg_partition[i] = (beg_partition[i - 1]
+ + (__last - __first) / num_pieces);
+ }
+ beg_partition[num_pieces] = (__last - access[num_pieces - 1]
+ + beg_partition[num_pieces - 1]);
+ access[num_pieces]= __last;
+ }
/** @brief Parallelization helper method: Given an input-access
sequence of known size, divide it into pieces of almost the
* @param n Sequence size
* @param num_pieces Number of pieces. */
template<typename _InputIterator>
- static void
- range_accessors(const _InputIterator __first, const _InputIterator __last, _InputIterator* access, size_type* beg_partition, const size_type n, const thread_index_t num_pieces, std::input_iterator_tag)
- {
- access[0] = __first;
- _InputIterator it= __first;
- for (int i=1; i< num_pieces; ++i)
- {
- for (int j=0; j< n/num_pieces; ++j)
+ static void
+ range_accessors(const _InputIterator __first,
+ const _InputIterator __last, _InputIterator* access,
+ size_type* beg_partition, const size_type n,
+ const thread_index_t num_pieces, std::input_iterator_tag)
+ {
+ access[0] = __first;
+ _InputIterator it= __first;
+ for (int i = 1; i < num_pieces; ++i)
+ {
+ for (int j=0; j< n/num_pieces; ++j)
++it;
- access[i] = it;
- beg_partition[i]= n/num_pieces + beg_partition[i-1];
+ access[i] = it;
+ beg_partition[i]= n / num_pieces + beg_partition[i - 1];
}
- access[num_pieces] = __last;
- beg_partition[num_pieces] = n - (num_pieces-1)*(n/num_pieces) + beg_partition[num_pieces-1];
- }
+ access[num_pieces] = __last;
+ beg_partition[num_pieces] = (n - (num_pieces - 1)
+ * (n / num_pieces)
+ + beg_partition[num_pieces - 1]);
+ }
/** @brief Initialize an array of concatenation problems for bulk
insertion. They are linked as a tree with (end - beg) leaves.
* @param parent Pointer to the parent concatenation problem.
*/
static concat_problem*
- _M_bulk_insertion_initialize_upper_problems(concat_problem** conc, const int beg, const int end, concat_problem* parent)
- {
- if (beg + 1 == end)
- {
- conc[2*beg]->par_problem = parent;
- return conc[2*beg];
- }
+ _M_bulk_insertion_initialize_upper_problems(concat_problem** conc,
+ const int beg, const int end,
+ concat_problem* parent)
+ {
+ if (beg + 1 == end)
+ {
+ conc[2*beg]->par_problem = parent;
+ return conc[2*beg];
+ }
- int size = end - beg;
- int mid = beg + size/2;
- conc[2*mid-1]->par_problem = parent;
- conc[2*mid-1]->left_problem = _M_bulk_insertion_initialize_upper_problems(conc, beg, mid, conc[2*mid-1]);
- conc[2*mid-1]->right_problem = _M_bulk_insertion_initialize_upper_problems(conc, mid, end, conc[2*mid-1]);
- return conc[2*mid-1];
- }
+ int size = end - beg;
+ int mid = beg + size/2;
+ conc[2*mid-1]->par_problem = parent;
+ conc[2*mid-1]->left_problem =
+ _M_bulk_insertion_initialize_upper_problems(conc, beg, mid,
+ conc[2*mid-1]);
+ conc[2*mid-1]->right_problem =
+ _M_bulk_insertion_initialize_upper_problems(conc, mid, end,
+ conc[2*mid-1]);
+ return conc[2*mid-1];
+ }
/** @brief Determine black height of a node recursively.
{
if (t == NULL)
return 0;
- int bh = black_height (static_cast<const _Rb_tree_node_ptr> (t->_M_left));
+ int bh = black_height(static_cast<const _Rb_tree_node_ptr>(t->_M_left));
if (t->_M_color == std::_S_black)
++bh;
return bh;
_GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1));
_GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2));
- _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color != std::_S_red and black_h_l > 0 : black_h_l == 0);
- _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color != std::_S_red and black_h_r > 0 : black_h_r == 0);
+ _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color != std::_S_red
+ and black_h_l > 0 : black_h_l == 0);
+ _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color != std::_S_red
+ and black_h_r > 0 : black_h_r == 0);
if (black_h_l > black_h_r)
if (root != NULL)
else
{
// XXX SHOULD BE the same as extract_min but slower.
- /*
- root = static_cast<_Rb_tree_node_ptr>(_Rb_tree_node_base::_S_minimum(r));
- split(r, _S_key(_Rb_tree_increment(root)), _S_key(root), root, t, r, black_h, black_h_r);
+ /* root = static_cast<_Rb_tree_node_ptr>(
+ _Rb_tree_node_base::_S_minimum(r));
+
+ split(r, _S_key(_Rb_tree_increment(root)),
+ _S_key(root), root, t, r, black_h, black_h_r);
*/
extract_min(r, root, r, black_h_r);
_GLIBCXX_PARALLEL_ASSERT(root != NULL);
- concatenate<LeftRight>(root, l, r, black_h_l, black_h_r, t, black_h);
+ concatenate<LeftRight>(root, l, r, black_h_l,
+ black_h_r, t, black_h);
}
}
else
{
// XXX SHOULD BE the same as extract_max but slower
/*
- root = static_cast<_Rb_tree_node_ptr>(_Rb_tree_node_base::_S_maximum(l));
- split(l, _S_key(root), _S_key(_Rb_tree_decrement(root)), root, l, t, black_h_l, black_h);
+ root = static_cast<_Rb_tree_node_ptr>(
+ _Rb_tree_node_base::_S_maximum(l));
+
+ split(l, _S_key(root), _S_key(_Rb_tree_decrement(root)),
+ root, l, t, black_h_l, black_h);
*/
extract_max(l, root, l, black_h_l);
_GLIBCXX_PARALLEL_ASSERT(root != NULL);
- concatenate<RightLeft>(root, r, l, black_h_r, black_h_l, t, black_h);
+ concatenate<RightLeft>(root, r, l, black_h_r,
+ black_h_l, t, black_h);
}
}
#ifndef NDEBUG
* @post @c t is correct red-black tree with height @c black_h.
*/
template<typename S>
- static void
- concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l,
- _Rb_tree_node_ptr r, int black_h_l, int black_h_r,
- _Rb_tree_node_ptr& t, int& black_h)
- {
- _Rb_tree_node_base* root = l;
- _Rb_tree_node_ptr parent = NULL;
- black_h = black_h_l;
- _GLIBCXX_PARALLEL_ASSERT(black_h_l >= black_h_r);
- while (black_h_l != black_h_r)
- {
- if (l->_M_color == std::_S_black)
- --black_h_l;
- parent = l;
- l = static_cast<_Rb_tree_node_ptr>(S::right(l));
- _GLIBCXX_PARALLEL_ASSERT((black_h_l == 0 and (l == NULL or l->_M_color == std::_S_red)) or (black_h_l != 0 and l != NULL));
- _GLIBCXX_PARALLEL_ASSERT((black_h_r == 0 and (r == NULL or r->_M_color == std::_S_red)) or (black_h_r != 0 and r != NULL));
- }
- if (l != NULL and l->_M_color == std::_S_red)
- {
- //the root needs to be black
- parent = l;
- l = static_cast<_Rb_tree_node_ptr>(S::right(l));
- }
- _GLIBCXX_PARALLEL_ASSERT(l != NULL ? l->_M_color == std::_S_black : true);
- _GLIBCXX_PARALLEL_ASSERT(r != NULL ? r->_M_color == std::_S_black : true);
- t = plant<S>(rt, l, r);
- t->_M_parent = parent;
- if (parent != NULL)
- {
- S::right(parent) = t;
- black_h += _Rb_tree_rebalance(t, root);
- t = static_cast<_Rb_tree_node_ptr> (root);
- }
- else
- {
- ++black_h;
- t->_M_color = std::_S_black;
- }
- _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black);
- }
+ static void
+ concatenate(const _Rb_tree_node_ptr rt, _Rb_tree_node_ptr l,
+ _Rb_tree_node_ptr r, int black_h_l, int black_h_r,
+ _Rb_tree_node_ptr& t, int& black_h)
+ {
+ _Rb_tree_node_base* root = l;
+ _Rb_tree_node_ptr parent = NULL;
+ black_h = black_h_l;
+ _GLIBCXX_PARALLEL_ASSERT(black_h_l >= black_h_r);
+ while (black_h_l != black_h_r)
+ {
+ if (l->_M_color == std::_S_black)
+ --black_h_l;
+ parent = l;
+ l = static_cast<_Rb_tree_node_ptr>(S::right(l));
+ _GLIBCXX_PARALLEL_ASSERT(
+ (black_h_l == 0 and (l == NULL or l->_M_color == std::_S_red))
+ or (black_h_l != 0 and l != NULL));
+ _GLIBCXX_PARALLEL_ASSERT(
+ (black_h_r == 0 and (r == NULL or r->_M_color == std::_S_red))
+ or (black_h_r != 0 and r != NULL));
+ }
+ if (l != NULL and l->_M_color == std::_S_red)
+ {
+ //the root needs to be black
+ parent = l;
+ l = static_cast<_Rb_tree_node_ptr>(S::right(l));
+ }
+
+ _GLIBCXX_PARALLEL_ASSERT(
+ l != NULL ? l->_M_color == std::_S_black : true);
+ _GLIBCXX_PARALLEL_ASSERT(
+ r != NULL ? r->_M_color == std::_S_black : true);
+
+ t = plant<S>(rt, l, r);
+ t->_M_parent = parent;
+ if (parent != NULL)
+ {
+ S::right(parent) = t;
+ black_h += _Rb_tree_rebalance(t, root);
+ t = static_cast<_Rb_tree_node_ptr> (root);
+ }
+ else
+ {
+ ++black_h;
+ t->_M_color = std::_S_black;
+ }
+ _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black);
+ }
/** @brief Split a tree according to key in three parts: a left
* child, a right child and an intermediate node.
* of the wrapping container
* @return Black height of t */
template<typename StrictlyLessOrEqual>
- int
- split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k,
- _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r,
- int& black_h_l, int& black_h_r,
- StrictlyLessOrEqual strictly_less_or_less_equal) const
- {
- if (t != NULL)
- {
- // Must be initialized, in case we never go left!!!
- root = NULL;
- int h = split_not_null(t, key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_less_equal);
+ int
+ split(_Rb_tree_node_ptr t, const key_type& key, const key_type& prev_k,
+ _Rb_tree_node_ptr& root, _Rb_tree_node_ptr& l,
+ _Rb_tree_node_ptr& r, int& black_h_l, int& black_h_r,
+ StrictlyLessOrEqual strictly_less_or_less_equal)
+ {
+ if (t != NULL)
+ {
+ // Must be initialized, in case we never go left!!!
+ root = NULL;
+ int h = split_not_null(t, key, prev_k, root, l, r, black_h_l,
+ black_h_r, strictly_less_or_less_equal);
#ifndef NDEBUG
- _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key));
- _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key));
- int count1, count2;
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1));
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2));
- _GLIBCXX_PARALLEL_ASSERT(root == NULL or base_type::_M_impl._M_key_compare(prev_k, base_type::_S_key(root)) and not base_type::_M_impl._M_key_compare(key, base_type::_S_key(root)));
- _GLIBCXX_PARALLEL_ASSERT(root != NULL or l==NULL or not base_type::_M_impl._M_key_compare(prev_k, base_type::_S_key(base_type::_S_maximum(l))));
+ _GLIBCXX_PARALLEL_ASSERT(
+ l == NULL or base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_maximum(l)),key));
+ _GLIBCXX_PARALLEL_ASSERT(
+ r == NULL or not base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_minimum(r)),key));
+ int count1, count2;
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(l, count1));
+ _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(r, count2));
+ _GLIBCXX_PARALLEL_ASSERT(
+ root == NULL or base_type::_M_impl._M_key_compare(
+ prev_k, base_type::_S_key(root))
+ and not base_type::_M_impl._M_key_compare(
+ key, base_type::_S_key(root)));
+ _GLIBCXX_PARALLEL_ASSERT(
+ root != NULL or l==NULL
+ or not base_type::_M_impl._M_key_compare(
+ prev_k, base_type::_S_key(base_type::_S_maximum(l))));
#endif
- return h;
- }
+ return h;
+ }
- r = NULL;
- root = NULL;
- l = NULL;
- black_h_r = 0;
- black_h_l = 0;
- return 0;
- }
+ r = NULL;
+ root = NULL;
+ l = NULL;
+ black_h_r = 0;
+ black_h_l = 0;
+ return 0;
+ }
/** @brief Split a tree according to key in three parts: a left
* child, a right child and an intermediate node.
* @pre t != NULL
* @return Black height of t */
template<typename StrictlyLessOrEqual>
- int
- split_not_null(const _Rb_tree_node_ptr t, const key_type& key,
- const key_type& prev_k, _Rb_tree_node_ptr& root,
- _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r, int& black_h_l,
- int& black_h_r,
- StrictlyLessOrEqual strictly_less_or_equal) const
- {
- _GLIBCXX_PARALLEL_ASSERT (t != NULL);
- int black_h, b_h;
- int black_node = 0;
- if (t->_M_color == std::_S_black)
- ++black_node;
- if (strictly_less_or_equal(key, base_type::_S_key(t)))
- {
- if (t->_M_left != NULL )
- {
- // t->M_right is at most one node
- // go to the left
- b_h = black_h = split_not_null( static_cast<_Rb_tree_node_ptr>(t->_M_left), key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_equal);
- // Moin root and right subtree to already existing right
- // half, leave left subtree.
- force_black_root(t->_M_right, b_h);
- concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r);
- }
- else
- {
- // t->M_right is at most one node
- r = t;
- black_h_r = black_node;
- force_black_root(r, black_h_r);
-
- black_h = 0;
- l = NULL;
- black_h_l = 0;
- }
- _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key));
- _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key));
- }
- else
- {
- if (t->_M_right != NULL )
- {
- // Go to the right.
- if (strictly_less_or_equal(prev_k, base_type::_S_key(t)))
- root = t;
- b_h = black_h = split_not_null(static_cast<_Rb_tree_node_ptr>(t->_M_right), key, prev_k, root, l, r, black_h_l, black_h_r, strictly_less_or_equal);
- // Join root and left subtree to already existing left
- // half, leave right subtree.
- force_black_root(t->_M_left, b_h);
- if (root != t)
- {
- // There was another point where we went right.
- concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l);
- }
- else
- {
- l = static_cast<_Rb_tree_node_ptr>(t->_M_left);
- black_h_l = b_h;
- }
- _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key));
- _GLIBCXX_PARALLEL_ASSERT(r == NULL or not base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_minimum(r)),key));
- }
- else
- {
- if (strictly_less_or_equal(prev_k, base_type::_S_key(t)))
- {
+ int
+ split_not_null(const _Rb_tree_node_ptr t, const key_type& key,
+ const key_type& prev_k, _Rb_tree_node_ptr& root,
+ _Rb_tree_node_ptr& l, _Rb_tree_node_ptr& r,
+ int& black_h_l, int& black_h_r,
+ StrictlyLessOrEqual strictly_less_or_equal)
+ {
+ _GLIBCXX_PARALLEL_ASSERT (t != NULL);
+ int black_h, b_h;
+ int black_node = 0;
+ if (t->_M_color == std::_S_black)
+ ++black_node;
+ if (strictly_less_or_equal(key, base_type::_S_key(t)))
+ {
+ if (t->_M_left != NULL )
+ {
+ // t->M_right is at most one node
+ // go to the left
+ b_h = black_h = split_not_null(
+ static_cast<_Rb_tree_node_ptr>(t->_M_left), key, prev_k,
+ root, l, r, black_h_l, black_h_r,
+ strictly_less_or_equal);
+ // Moin root and right subtree to already existing right
+ // half, leave left subtree.
+ force_black_root(t->_M_right, b_h);
+ concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right),
+ black_h_r, b_h, r, black_h_r);
+ }
+ else
+ {
+ // t->M_right is at most one node
+ r = t;
+ black_h_r = black_node;
+ force_black_root(r, black_h_r);
+
+ black_h = 0;
+ l = NULL;
+ black_h_l = 0;
+ }
+ _GLIBCXX_PARALLEL_ASSERT(
+ l == NULL or base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_maximum(l)),key));
+ _GLIBCXX_PARALLEL_ASSERT(
+ r == NULL or not base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_minimum(r)),key));
+ }
+ else
+ {
+ if (t->_M_right != NULL )
+ {
+ // Go to the right.
+ if (strictly_less_or_equal(prev_k, base_type::_S_key(t)))
root = t;
- l= static_cast<_Rb_tree_node_ptr>(t->_M_left);
- make_black_leaf(l, black_h_l);
- _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key));
- }
- else
- {
- l= t;
- black_h_l = black_node;
- force_black_root(l, black_h_l);
- _GLIBCXX_PARALLEL_ASSERT(l == NULL or base_type::_M_impl._M_key_compare(base_type::_S_key(base_type::_S_maximum(l)),key));
- }
+ b_h = black_h = split_not_null(
+ static_cast<_Rb_tree_node_ptr>(t->_M_right), key, prev_k,
+ root, l, r, black_h_l, black_h_r, strictly_less_or_equal);
+ // Join root and left subtree to already existing left
+ // half, leave right subtree.
+ force_black_root(t->_M_left, b_h);
+ if (root != t)
+ {
+ // There was another point where we went right.
+ concatenate(t, static_cast<_Rb_tree_node_ptr>(
+ t->_M_left), l, b_h, black_h_l,
+ l, black_h_l);
+ }
+ else
+ {
+ l = static_cast<_Rb_tree_node_ptr>(t->_M_left);
+ black_h_l = b_h;
+ }
+ _GLIBCXX_PARALLEL_ASSERT(
+ l == NULL or base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_maximum(l)),key));
+ _GLIBCXX_PARALLEL_ASSERT(
+ r == NULL or not base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_minimum(r)),key));
+ }
+ else
+ {
+ if (strictly_less_or_equal(prev_k, base_type::_S_key(t)))
+ {
+ root = t;
+ l= static_cast<_Rb_tree_node_ptr>(t->_M_left);
+ make_black_leaf(l, black_h_l);
+ _GLIBCXX_PARALLEL_ASSERT(
+ l == NULL or base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_maximum(l)),key));
+ }
+ else
+ {
+ l= t;
+ black_h_l = black_node;
+ force_black_root(l, black_h_l);
+ _GLIBCXX_PARALLEL_ASSERT(
+ l == NULL or base_type::_M_impl._M_key_compare(
+ base_type::_S_key(base_type::_S_maximum(l)),key));
+ }
- r = NULL;
- black_h = 0;
- black_h_r = 0;
- }
- }
- return black_h + black_node;
- }
+ r = NULL;
+ black_h = 0;
+ black_h_r = 0;
+ }
+ }
+ return black_h + black_node;
+ }
/** @brief Color the root black and update the black height accordingly.
*
* @param t Root of the tree.
* @param black_h Black height of the tree @c t (out) */
- static void force_black_root(_Rb_tree_node_base* t, int& black_h)
+ static void
+ force_black_root(_Rb_tree_node_base* t, int& black_h)
{
if (t != NULL and t->_M_color == std::_S_red)
{
* @return Black height of the original tree */
int
extract_min(const _Rb_tree_node_ptr t, _Rb_tree_node_ptr& root,
- _Rb_tree_node_ptr& r, int& black_h_r) const
+ _Rb_tree_node_ptr& r, int& black_h_r)
{
_GLIBCXX_PARALLEL_ASSERT (t != NULL);
int black_h, b_h;
{
// t->M_right is at most one node
// go to the left
- b_h = black_h = extract_min( static_cast<_Rb_tree_node_ptr>(t->_M_left), root, r, black_h_r);
+ b_h = black_h = extract_min(
+ static_cast<_Rb_tree_node_ptr>(t->_M_left), root, r, black_h_r);
// Join root and right subtree to already existing right
// half, leave left subtree
force_black_root(t->_M_right, b_h);
- concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r);
+ concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right),
+ black_h_r, b_h, r, black_h_r);
}
else
{
if (t->_M_right != NULL )
{
- b_h = black_h = extract_max(static_cast<_Rb_tree_node_ptr>(t->_M_right), root, l, black_h_l);
+ b_h = black_h = extract_max(
+ static_cast<_Rb_tree_node_ptr>(t->_M_right), root, l, black_h_l);
// Join root and left subtree to already existing left half,
// leave right subtree.
force_black_root(t->_M_left, b_h);
- concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l);
+ concatenate(t, static_cast<_Rb_tree_node_ptr>(
+ t->_M_left), l, b_h, black_h_l, l, black_h_l);
}
else
{
int black_node = 0;
if (t->_M_color == std::_S_black)
++black_node;
- if (not (base_type::_M_impl._M_key_compare(base_type::_S_key(t), key)))
+ if (not (base_type::_M_impl._M_key_compare(base_type::_S_key(t),
+ key)))
{
// Go to the left.
- b_h = black_h = split( static_cast<_Rb_tree_node_ptr>(t->_M_left), key, l, r, black_h_l, black_h_r);
+ b_h = black_h = split(
+ static_cast<_Rb_tree_node_ptr>(t->_M_left), key, l, r,
+ black_h_l, black_h_r);
// Join root and right subtree to already existing right
// half, leave left subtree.
force_black_root(t->_M_right, b_h);
- concatenate(t, r, static_cast<_Rb_tree_node_ptr>(t->_M_right), black_h_r, b_h, r, black_h_r);
+ concatenate(t, r, static_cast<_Rb_tree_node_ptr>(
+ t->_M_right), black_h_r, b_h, r, black_h_r);
}
else
{
// Go to the right.
- b_h = black_h = split(static_cast<_Rb_tree_node_ptr>(t->_M_right), key, l, r, black_h_l, black_h_r);
+ b_h = black_h = split(static_cast<_Rb_tree_node_ptr>(
+ t->_M_right), key, l, r,
+ black_h_l, black_h_r);
// Join root and left subtree to already existing left
// half, leave right subtree.
force_black_root(t->_M_left, b_h);
- concatenate(t, static_cast<_Rb_tree_node_ptr>(t->_M_left), l, b_h, black_h_l, l, black_h_l);
+ concatenate(t, static_cast<_Rb_tree_node_ptr>(
+ t->_M_left), l, b_h, black_h_l, l, black_h_l);
}
return black_h + black_node;
}
* of the wrapping container
* @return Resulting tree after insertion */
template<typename StrictlyLessOrLessEqual>
- _Rb_tree_node_ptr
- _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t,
- size_type& existing, int& black_h,
- StrictlyLessOrLessEqual strictly_less_or_less_equal)
- {
- _GLIBCXX_PARALLEL_ASSERT(t != NULL);
- if (_M_insert_local_top_down(t, new_t, NULL, NULL, true, strictly_less_or_less_equal))
- {
- t->_M_parent = NULL;
- black_h += _Rb_tree_rebalance(new_t, t);
- _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black);
- return static_cast<_Rb_tree_node_ptr>(t);
- }
+ _Rb_tree_node_ptr
+ _M_insert_local(_Rb_tree_node_base* t, const _Rb_tree_node_ptr new_t,
+ size_type& existing, int& black_h,
+ StrictlyLessOrLessEqual strictly_less_or_less_equal)
+ {
+ _GLIBCXX_PARALLEL_ASSERT(t != NULL);
+ if (_M_insert_local_top_down(t, new_t, NULL, NULL,
+ true, strictly_less_or_less_equal))
+ {
+ t->_M_parent = NULL;
+ black_h += _Rb_tree_rebalance(new_t, t);
+ _GLIBCXX_PARALLEL_ASSERT(t->_M_color == std::_S_black);
+ return static_cast<_Rb_tree_node_ptr>(t);
+ }
else
{
base_type::_M_destroy_node(new_t);
* @return Success of the insertion
*/
template<typename StrictlyLessOrLessEqual>
- bool
- _M_insert_local_top_down(_Rb_tree_node_base* t,
- const _Rb_tree_node_ptr new_t,
- _Rb_tree_node_base* eq_t,
- _Rb_tree_node_base* parent, const bool is_left,
- StrictlyLessOrLessEqual strictly_less_or_less_equal) const
- {
- if (t != NULL)
- {
- if (strictly_less_or_less_equal(_S_key(new_t), _S_key(static_cast<_Rb_tree_node_ptr>(t))))
- {
- return _M_insert_local_top_down(t->_M_left, new_t, eq_t, t, true, strictly_less_or_less_equal);
- }
- else
- {
- return _M_insert_local_top_down(t->_M_right, new_t, t, t, false, strictly_less_or_less_equal);
- }
- }
+ bool
+ _M_insert_local_top_down(_Rb_tree_node_base* t,
+ const _Rb_tree_node_ptr new_t,
+ _Rb_tree_node_base* eq_t,
+ _Rb_tree_node_base* parent, const bool is_left,
+ StrictlyLessOrLessEqual
+ strictly_less_or_less_equal) const
+ {
+ if (t != NULL)
+ {
+ if (strictly_less_or_less_equal(
+ _S_key(new_t), _S_key(static_cast<_Rb_tree_node_ptr>(t))))
+ return _M_insert_local_top_down(t->_M_left, new_t, eq_t, t, true,
+ strictly_less_or_less_equal);
+ else
+ return _M_insert_local_top_down(t->_M_right, new_t, t, t, false,
+ strictly_less_or_less_equal);
+ }
- _GLIBCXX_PARALLEL_ASSERT(parent != NULL);
+ _GLIBCXX_PARALLEL_ASSERT(parent != NULL);
- // Base case.
- if (eq_t == NULL or strictly_less_or_less_equal(_S_key(static_cast<_Rb_tree_node_ptr>(eq_t)), _S_key(new_t)))
- {
- // The element to be inserted did not existed.
- if (is_left)
- {
+ // Base case.
+ if (eq_t == NULL or strictly_less_or_less_equal(
+ _S_key(static_cast<_Rb_tree_node_ptr>(eq_t)), _S_key(new_t)))
+ {
+ // The element to be inserted did not existed.
+ if (is_left)
parent->_M_left = new_t;
- }
- else
- {
+ else
parent->_M_right = new_t;
- }
- new_t->_M_parent = parent;
- new_t->_M_left = NULL;
- new_t->_M_right = NULL;
- new_t->_M_color = std::_S_red;
+ new_t->_M_parent = parent;
+ new_t->_M_left = NULL;
+ new_t->_M_right = NULL;
+ new_t->_M_color = std::_S_red;
- return true;
- }
- else
- return false;
- }
+ return true;
+ }
+ else
+ return false;
+ }
/** @brief Rebalance a tree locally.
*
if (__root->_M_color == std::_S_red)
{
__root->_M_color = std::_S_black;
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(static_cast<typename base_type::_Const_Link_type>(__root)));
+ _GLIBCXX_PARALLEL_ASSERT(
+ rb_verify_tree(static_cast<typename base_type::
+ _Const_Link_type>(__root)));
return 1;
}
- _GLIBCXX_PARALLEL_ASSERT(rb_verify_tree(static_cast<typename base_type::_Const_Link_type>(__root)));
+ _GLIBCXX_PARALLEL_ASSERT(
+ rb_verify_tree(static_cast<typename base_type::
+ _Const_Link_type>(__root)));
return 0;
}
* @return Tree correct.
*/
bool
- rb_verify_tree(const typename base_type::_Const_Link_type __x, int& count) const
+ rb_verify_tree(const typename base_type::_Const_Link_type __x,
+ int& count) const
{
int bh;
return rb_verify_tree_node(__x) and rb_verify_tree(__x, count, bh);
return true;
else
{
- return rb_verify_node(__x) and
- rb_verify_tree_node(base_type::_S_left(__x)) and
- rb_verify_tree_node( base_type::_S_right(__x));
+ return rb_verify_node(__x)
+ and rb_verify_tree_node(base_type::_S_left(__x))
+ and rb_verify_tree_node( base_type::_S_right(__x));
}
}
if (__x->_M_color == std::_S_red)
if ((__L && __L->_M_color == std::_S_red)
|| (__R && __R->_M_color == std::_S_red))
- {
- return false;
- }
+ return false;
+
if (__L != NULL)
{
- __L = static_cast<typename base_type::_Const_Link_type>(base_type::_S_maximum(__L));
- if (base_type::_M_impl._M_key_compare(base_type::_S_key(__x), base_type::_S_key(__L)))
- {
- return false;
- }
+ __L = static_cast<typename base_type::_Const_Link_type>(
+ base_type::_S_maximum(__L));
+ if (base_type::_M_impl._M_key_compare(base_type::_S_key(__x),
+ base_type::_S_key(__L)))
+ return false;
}
if (__R != NULL)
{
- __R = static_cast<typename base_type::_Const_Link_type>(base_type::_S_minimum(__R));
- if (base_type::_M_impl._M_key_compare(base_type::_S_key(__R), base_type::_S_key(__x)))
- {
- return false;
- }
+ __R = static_cast<typename base_type::_Const_Link_type>(
+ base_type::_S_minimum(__R));
+ if (base_type::_M_impl._M_key_compare(base_type::_S_key(__R),
+ base_type::_S_key(__x)))
+ return false;
}
return true;
bool
rb_verify()
{
- if (base_type::_M_impl._M_node_count == 0 || base_type::begin() == base_type::end())
+ if (base_type::_M_impl._M_node_count == 0
+ || base_type::begin() == base_type::end())
{
- bool res = base_type::_M_impl._M_node_count == 0 && base_type::begin() == base_type::end()
+ bool res = base_type::_M_impl._M_node_count == 0
+ && base_type::begin() == base_type::end()
&& base_type::_M_impl._M_header._M_left ==base_type::_M_end()
&& base_type::_M_impl._M_header._M_right == base_type::_M_end();
_GLIBCXX_PARALLEL_ASSERT(res);
return res;
}
size_type i=0;
- unsigned int __len = _Rb_tree_black_count(base_type::_M_leftmost(), base_type::_M_root());
- for (typename base_type::const_iterator __it =base_type::begin(); __it != base_type::end(); ++__it)
+ unsigned int __len = _Rb_tree_black_count(base_type::_M_leftmost(),
+ base_type::_M_root());
+ for (typename base_type::const_iterator __it =base_type::begin();
+ __it != base_type::end(); ++__it)
{
- typename base_type::_Const_Link_type __x = static_cast<typename base_type::_Const_Link_type>(__it._M_node);
+ typename base_type::_Const_Link_type __x =
+ static_cast<typename base_type::_Const_Link_type>(__it._M_node);
if (not rb_verify_node(__x)) return false;
- if (!base_type::_S_left(__x)&& !base_type::_S_right(__x) && _Rb_tree_black_count(__x,base_type::_M_root()) != __len)
+ if (!base_type::_S_left(__x)&& !base_type::_S_right(__x)
+ && _Rb_tree_black_count(__x,base_type::_M_root()) != __len)
{
_GLIBCXX_PARALLEL_ASSERT(false);
return false;
if (i != base_type::_M_impl._M_node_count)
printf("%ld != %ld\n", i, base_type::_M_impl._M_node_count);
- if (base_type::_M_leftmost() != std::_Rb_tree_node_base::_S_minimum(base_type::_M_root()))
+ if (base_type::_M_leftmost()
+ != std::_Rb_tree_node_base::_S_minimum(base_type::_M_root()))
{
_GLIBCXX_PARALLEL_ASSERT(false);
return false;
}
- if (base_type::_M_rightmost() != std::_Rb_tree_node_base::_S_maximum(base_type::_M_root()))
+ if (base_type::_M_rightmost()
+ != std::_Rb_tree_node_base::_S_maximum(base_type::_M_root()))
{
_GLIBCXX_PARALLEL_ASSERT(false);
return false;
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* @param result Begin iterator of result sequence.
* @param binary_pred Equality predicate.
* @return End iterator of result sequence. */
-template<
- typename InputIterator,
- class OutputIterator,
- class BinaryPredicate>
- inline OutputIterator
+template<typename InputIterator,
+ class OutputIterator,
+ class BinaryPredicate>
+ OutputIterator
parallel_unique_copy(InputIterator first, InputIterator last,
OutputIterator result, BinaryPredicate binary_pred)
{
{
# pragma omp single
{
- num_threads = omp_get_num_threads();
- borders = new difference_type[num_threads + 2];
- equally_split(size, num_threads + 1, borders);
- counter = new difference_type[num_threads + 1];
+ num_threads = omp_get_num_threads();
+ borders = new difference_type[num_threads + 2];
+ equally_split(size, num_threads + 1, borders);
+ counter = new difference_type[num_threads + 1];
}
thread_index_t iam = omp_get_thread_num();
begin = borders[0] + 1; // == 1
end = borders[iam + 1];
- i++;
+ ++i;
*out++ = *first;
for (InputIterator iter = first + begin; iter < first + end; ++iter)
{
if (!binary_pred(*iter, *(iter-1)))
{
- i++;
+ ++i;
*out++ = *iter;
}
}
for (InputIterator iter = first + begin; iter < first + end; ++iter)
{
- if (!binary_pred(*iter, *(iter-1)))
- {
- i++;
- }
- }
+ if (!binary_pred(*iter, *(iter - 1)))
+ ++i;
+ }
}
counter[iam] = i;
if (iam == 0)
{
- for (int t = 0; t < num_threads; t++)
+ for (int t = 0; t < num_threads; ++t)
begin_output += counter[t];
i = 0;
for (InputIterator iter = first + begin; iter < first + end; ++iter)
{
- if (iter == first || !binary_pred(*iter, *(iter-1)))
+ if (iter == first || !binary_pred(*iter, *(iter - 1)))
{
- i++;
+ ++i;
*iter_out++ = *iter;
}
}
for (InputIterator iter = first + begin; iter < first + end; ++iter)
{
if (!binary_pred(*iter, *(iter-1)))
- {
- *iter_out++ = *iter;
- }
- }
+ *iter_out++ = *iter;
+ }
}
}
OutputIterator result)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type;
-
- return parallel_unique_copy(first, last, result, std::equal_to<value_type>());
+ return parallel_unique_copy(first, last, result,
+ std::equal_to<value_type>());
}
}//namespace __gnu_parallel
// -*- C++ -*-
-// Copyright (C) 2007 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
* std::count_n()).
* @return User-supplied functor (that may contain a part of the result).
*/
-template<
- typename RandomAccessIterator,
- typename Op,
- typename Fu,
- typename Red,
- typename Result>
+template<typename RandomAccessIterator,
+ typename Op,
+ typename Fu,
+ typename Red,
+ typename Result>
Op
- for_each_template_random_access_workstealing(
- RandomAccessIterator begin,
- RandomAccessIterator end,
- Op op, Fu& f, Red r,
- Result base, Result& output,
- typename std::iterator_traits<RandomAccessIterator>::difference_type
- bound)
+ for_each_template_random_access_workstealing(RandomAccessIterator begin,
+ RandomAccessIterator end,
+ Op op, Fu& f, Red r,
+ Result base, Result& output,
+ typename std::iterator_traits
+ <RandomAccessIterator>::
+ difference_type bound)
{
_GLIBCXX_CALL(end - begin)
// This thread is currently working.
# pragma omp atomic
- busy++;
+ ++busy;
iam_working = true;
// Cannot use volatile variable directly.
difference_type my_first = my_job.first;
result = f(op, begin + my_first);
- my_job.first++;
- my_job.load--;
+ ++my_job.first;
+ --my_job.load;
}
RandomAccessIterator current;
my_job.load = my_job.last - my_job.first + 1;
for (difference_type job_counter = 0;
job_counter < chunk_size && current_job <= my_job.last;
- job_counter++)
+ ++job_counter)
{
// Yes: process it!
current = begin + current_job;
- current_job++;
+ ++current_job;
// Do actual work.
result = r(result, f(op, current));
{
// This thread no longer has work.
# pragma omp atomic
- busy--;
+ --busy;
iam_working = false;
}
// Has potential work again.
# pragma omp atomic
- busy++;
+ ++busy;
iam_working = true;
# pragma omp flush(busy)