rearrange.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 <functional>
  16. #include <iterator>
  17. #include <type_traits>
  18. #include <vector>
  19. #include <cassert>
  20. #include <boost/sort/common/util/traits.hpp>
  21. namespace boost
  22. {
  23. namespace sort
  24. {
  25. namespace common
  26. {
  27. template<class Iter_data>
  28. struct filter_iterator
  29. {
  30. //-----------------------------------------------------------------------
  31. // Variables
  32. //-----------------------------------------------------------------------
  33. Iter_data origin;
  34. //-----------------------------------------------------------------------
  35. // Functions
  36. //-----------------------------------------------------------------------
  37. filter_iterator(Iter_data global_first): origin(global_first) { };
  38. size_t operator ()(Iter_data itx) const
  39. {
  40. return size_t(itx - origin);
  41. }
  42. };
  43. struct filter_pos
  44. {
  45. size_t operator ()(size_t pos) const { return pos; };
  46. };
  47. //
  48. //-----------------------------------------------------------------------------
  49. // function : rearrange
  50. /// @brief This function transform a logical sort of the elements in the index
  51. /// of iterators in a physical sort.
  52. //
  53. /// @param global_first : iterator to the first element of the data
  54. /// @param [in] index : vector of the iterators
  55. //-----------------------------------------------------------------------------
  56. template<class Iter_data, class Iter_index, class Filter_pos>
  57. void rearrange(Iter_data global_first, Iter_index itx_first,
  58. Iter_index itx_last, Filter_pos pos)
  59. {
  60. //-----------------------------------------------------------------------
  61. // Metaprogramming
  62. //-----------------------------------------------------------------------
  63. typedef util::value_iter<Iter_data> value_data;
  64. typedef util::value_iter<Iter_index> value_index;
  65. //-------------------------------------------------------------------------
  66. // Code
  67. //-------------------------------------------------------------------------
  68. assert((itx_last - itx_first) >= 0);
  69. size_t pos_dest, pos_src, pos_ini;
  70. size_t nelem = size_t(itx_last - itx_first);
  71. Iter_data data = global_first;
  72. Iter_index index = itx_first;
  73. pos_ini = 0;
  74. while (pos_ini < nelem)
  75. {
  76. while (pos_ini < nelem && pos(index[pos_ini]) == pos_ini)
  77. ++pos_ini;
  78. if (pos_ini == nelem) return;
  79. pos_dest = pos_src = pos_ini;
  80. value_data aux = std::move(data[pos_ini]);
  81. value_index itx_src = std::move(index[pos_ini]);
  82. while ((pos_src = pos(itx_src)) != pos_ini)
  83. {
  84. using std::swap;
  85. data[pos_dest] = std::move(data[pos_src]);
  86. 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