rearrange.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //----------------------------------------------------------------------------
  2. /// @file rearrange.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_COMMON_REARRANGE_HPP
  14. #define __BOOST_SORT_COMMON_REARRANGE_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. #include <cassert>
  22. namespace boost
  23. {
  24. namespace sort
  25. {
  26. namespace common
  27. {
  28. template<class Iter_data>
  29. struct filter_iterator
  30. {
  31. //-----------------------------------------------------------------------
  32. // Variables
  33. //-----------------------------------------------------------------------
  34. Iter_data origin;
  35. //-----------------------------------------------------------------------
  36. // Functions
  37. //-----------------------------------------------------------------------
  38. filter_iterator(Iter_data global_first): origin(global_first) { };
  39. size_t operator ()(Iter_data itx) const
  40. {
  41. return size_t(itx - origin);
  42. }
  43. };
  44. struct filter_pos
  45. {
  46. size_t operator ()(size_t pos) const { return pos; };
  47. };
  48. //
  49. //-----------------------------------------------------------------------------
  50. // function : rearrange
  51. /// @brief This function transform a logical sort of the elements in the index
  52. /// of iterators in a physical sort.
  53. //
  54. /// @param global_first : iterator to the first element of the data
  55. /// @param [in] index : vector of the iterators
  56. //-----------------------------------------------------------------------------
  57. template<class Iter_data, class Iter_index, class Filter_pos>
  58. void rearrange(Iter_data global_first, Iter_index itx_first,
  59. Iter_index itx_last, Filter_pos pos)
  60. {
  61. //-----------------------------------------------------------------------
  62. // Metaprogramming
  63. //-----------------------------------------------------------------------
  64. typedef util::value_iter<Iter_data> value_data;
  65. typedef util::value_iter<Iter_index> value_index;
  66. //-------------------------------------------------------------------------
  67. // Code
  68. //-------------------------------------------------------------------------
  69. assert((itx_last - itx_first) >= 0);
  70. size_t pos_dest, pos_src, pos_ini;
  71. size_t nelem = size_t(itx_last - itx_first);
  72. Iter_data data = global_first;
  73. Iter_index index = itx_first;
  74. pos_ini = 0;
  75. while (pos_ini < nelem)
  76. {
  77. while (pos_ini < nelem and pos(index[pos_ini]) == pos_ini)
  78. ++pos_ini;
  79. if (pos_ini == nelem) return;
  80. pos_dest = pos_src = pos_ini;
  81. value_data aux = std::move(data[pos_ini]);
  82. value_index itx_src = std::move(index[pos_ini]);
  83. while ((pos_src = pos(itx_src)) != pos_ini)
  84. {
  85. data[pos_dest] = std::move(data[pos_src]);
  86. std::swap(itx_src, index[pos_src]);
  87. pos_dest = pos_src;
  88. };
  89. data[pos_dest] = std::move(aux);
  90. index[pos_ini] = std::move(itx_src);
  91. ++pos_ini;
  92. };
  93. };
  94. /*
  95. //
  96. //-----------------------------------------------------------------------------
  97. // function : rearrange_pos
  98. /// @brief This function transform a logical sort of the elements in the index
  99. /// of iterators in a physical sort.
  100. //
  101. /// @param global_first : iterator to the first element of the data
  102. /// @param [in] index : vector of the iterators
  103. //-----------------------------------------------------------------------------
  104. template < class Iter_t, class Number >
  105. void rearrange_pos (Iter_t global_first, std::vector< Number> &index)
  106. {
  107. //-------------------------------------------------------------------------
  108. // METAPROGRAMMING AND DEFINITIONS
  109. //-------------------------------------------------------------------------
  110. static_assert ( std::is_integral<Number>::value, "Incompatible Types");
  111. typedef iter_value< Iter_t > value_t;
  112. //-------------------------------------------------------------------------
  113. // CODE
  114. //-------------------------------------------------------------------------
  115. size_t pos_dest = 0;
  116. size_t pos_src = 0;
  117. size_t pos_ini = 0;
  118. size_t nelem = index.size ( );
  119. Iter_t it_dest (global_first), it_src(global_first);
  120. while (pos_ini < nelem)
  121. {
  122. while (pos_ini < nelem and
  123. index[pos_ini] == pos_ini)
  124. {
  125. ++pos_ini;
  126. };
  127. if (pos_ini == nelem) return;
  128. pos_dest = pos_src = pos_ini;
  129. it_dest = global_first + pos_dest;
  130. value_t Aux = std::move (*it_dest);
  131. while ((pos_src = index[pos_dest]) != pos_ini)
  132. {
  133. index[pos_dest] = it_dest - global_first;
  134. it_src = global_first + pos_src;
  135. *it_dest = std::move (*it_src);
  136. it_dest = it_src;
  137. pos_dest = pos_src;
  138. };
  139. *it_dest = std::move (Aux);
  140. index[pos_dest] = it_dest - global_first;
  141. ++pos_ini;
  142. };
  143. };
  144. */
  145. //
  146. //****************************************************************************
  147. };// End namespace common
  148. };// End namespace sort
  149. };// End namespace boost
  150. //****************************************************************************
  151. //
  152. #endif