indirect.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //----------------------------------------------------------------------------
  2. /// @file indirect.hpp
  3. /// @brief Indirect algorithm
  4. ///
  5. /// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n
  6. /// Distributed under the Boost Software License, Version 1.0.\n
  7. /// ( See accompanying file LICENSE_1_0.txt or copy at
  8. /// http://www.boost.org/LICENSE_1_0.txt )
  9. /// @version 0.1
  10. ///
  11. /// @remarks
  12. //-----------------------------------------------------------------------------
  13. #ifndef __BOOST_SORT_PARALLEL_COMMON_INDIRECT_HPP
  14. #define __BOOST_SORT_PARALLEL_COMMON_INDIRECT_HPP
  15. //#include <boost/sort/common/atomic.hpp>
  16. #include <boost/sort/common/util/traits.hpp>
  17. #include <functional>
  18. #include <iterator>
  19. #include <type_traits>
  20. #include <vector>
  21. namespace boost
  22. {
  23. namespace sort
  24. {
  25. namespace common
  26. {
  27. //
  28. //---------------------------------------------------------------------------
  29. /// @struct less_ptr_no_null
  30. ///
  31. /// @remarks this is the comparison object for pointers. Compare the objects
  32. /// pointed by the iterators
  33. //---------------------------------------------------------------------------
  34. template<class Iter_t, class Compare = util::compare_iter<Iter_t> >
  35. struct less_ptr_no_null
  36. {
  37. //----------------------------- Variables -----------------------
  38. Compare comp; // comparison object of the elements pointed by Iter_t
  39. //------------------------------------------------------------------------
  40. // function : less_ptr_no_null
  41. /// @brief constructor from a Compare object
  42. /// @param C1 : comparison object
  43. //-----------------------------------------------------------------------
  44. less_ptr_no_null(Compare C1 = Compare()): comp(C1) { };
  45. //------------------------------------------------------------------------
  46. // function : operator ( )
  47. /// @brief Make the comparison of the objects pointed by T1 and T2, using
  48. // the internal comp
  49. //
  50. /// @param T1 : first iterator
  51. /// @param T2 : second iterator
  52. /// @return bool result of the comparison
  53. //-----------------------------------------------------------------------
  54. bool operator( )(Iter_t T1, Iter_t T2) const
  55. {
  56. return comp(*T1, *T2);
  57. };
  58. };
  59. //
  60. //-----------------------------------------------------------------------------
  61. // function : create_index
  62. /// @brief From a vector of objects, create a vector of iterators to
  63. /// the objects
  64. ///
  65. /// @param first : iterator to the first element of the range
  66. /// @param last : iterator to the element after the last of the range
  67. /// @param index : vector where store the iterators
  68. //-----------------------------------------------------------------------------
  69. template<class Iter_t>
  70. static void create_index(Iter_t first, Iter_t last, std::vector<Iter_t> &index)
  71. {
  72. auto nelem = last - first;
  73. assert(nelem >= 0);
  74. index.clear();
  75. index.reserve(nelem);
  76. for (; first != last; ++first) index.push_back(first);
  77. };
  78. //
  79. //-----------------------------------------------------------------------------
  80. // function : sort_index
  81. /// @brief This function transform a logical sort of the elements in the index
  82. /// in a physical sort
  83. //
  84. /// @param global_first : iterator to the first element of the data
  85. /// @param [in] index : vector of the iterators
  86. //-----------------------------------------------------------------------------
  87. template<class Iter_t>
  88. static void sort_index(Iter_t global_first, std::vector<Iter_t> &index)
  89. {
  90. typedef util::value_iter<Iter_t> value_t;
  91. size_t pos_dest = 0;
  92. size_t pos_src = 0;
  93. size_t pos_in_vector = 0;
  94. size_t nelem = index.size();
  95. Iter_t it_dest, it_src;
  96. while (pos_in_vector < nelem)
  97. {
  98. while (pos_in_vector < nelem and
  99. (size_t(index[pos_in_vector] - global_first)) == pos_in_vector)
  100. {
  101. ++pos_in_vector;
  102. };
  103. if (pos_in_vector == nelem) return;
  104. pos_dest = pos_src = pos_in_vector;
  105. it_dest = global_first + pos_dest;
  106. value_t Aux = std::move(*it_dest);
  107. while ((pos_src = (size_t(index[pos_dest] - global_first)))
  108. != pos_in_vector)
  109. {
  110. index[pos_dest] = it_dest;
  111. it_src = global_first + pos_src;
  112. *it_dest = std::move(*it_src);
  113. it_dest = it_src;
  114. pos_dest = pos_src;
  115. };
  116. *it_dest = std::move(Aux);
  117. index[pos_dest] = it_dest;
  118. ++pos_in_vector;
  119. };
  120. };
  121. template<class func, class Iter_t, class Compare = compare_iter<Iter_t> >
  122. static void indirect_sort(func method, Iter_t first, Iter_t last, Compare comp)
  123. {
  124. auto nelem = (last - first);
  125. assert(nelem >= 0);
  126. if (nelem < 2) return;
  127. std::vector<Iter_t> index;
  128. index.reserve((size_t) nelem);
  129. create_index(first, last, index);
  130. less_ptr_no_null<Iter_t, Compare> index_comp(comp);
  131. method(index.begin(), index.end(), index_comp);
  132. sort_index(first, index);
  133. };
  134. //
  135. //****************************************************************************
  136. };// End namespace common
  137. };// End namespace sort
  138. };// End namespace boost
  139. //****************************************************************************
  140. //
  141. #endif