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 <ciso646>
  16. #include <functional>
  17. #include <iterator>
  18. #include <type_traits>
  19. #include <vector>
  20. #include <cassert>
  21. #include <boost/sort/common/util/traits.hpp>
  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. using std::swap;
  86. data[pos_dest] = std::move(data[pos_src]);
  87. swap(itx_src, index[pos_src]);
  88. pos_dest = pos_src;
  89. };
  90. data[pos_dest] = std::move(aux);
  91. index[pos_ini] = std::move(itx_src);
  92. ++pos_ini;
  93. };
  94. };
  95. /*
  96. //
  97. //-----------------------------------------------------------------------------
  98. // function : rearrange_pos
  99. /// @brief This function transform a logical sort of the elements in the index
  100. /// of iterators in a physical sort.
  101. //
  102. /// @param global_first : iterator to the first element of the data
  103. /// @param [in] index : vector of the iterators
  104. //-----------------------------------------------------------------------------
  105. template < class Iter_t, class Number >
  106. void rearrange_pos (Iter_t global_first, std::vector< Number> &index)
  107. {
  108. //-------------------------------------------------------------------------
  109. // METAPROGRAMMING AND DEFINITIONS
  110. //-------------------------------------------------------------------------
  111. static_assert ( std::is_integral<Number>::value, "Incompatible Types");
  112. typedef iter_value< Iter_t > value_t;
  113. //-------------------------------------------------------------------------
  114. // CODE
  115. //-------------------------------------------------------------------------
  116. size_t pos_dest = 0;
  117. size_t pos_src = 0;
  118. size_t pos_ini = 0;
  119. size_t nelem = index.size ( );
  120. Iter_t it_dest (global_first), it_src(global_first);
  121. while (pos_ini < nelem)
  122. {
  123. while (pos_ini < nelem and
  124. index[pos_ini] == pos_ini)
  125. {
  126. ++pos_ini;
  127. };
  128. if (pos_ini == nelem) return;
  129. pos_dest = pos_src = pos_ini;
  130. it_dest = global_first + pos_dest;
  131. value_t Aux = std::move (*it_dest);
  132. while ((pos_src = index[pos_dest]) != pos_ini)
  133. {
  134. index[pos_dest] = it_dest - global_first;
  135. it_src = global_first + pos_src;
  136. *it_dest = std::move (*it_src);
  137. it_dest = it_src;
  138. pos_dest = pos_src;
  139. };
  140. *it_dest = std::move (Aux);
  141. index[pos_dest] = it_dest - global_first;
  142. ++pos_ini;
  143. };
  144. };
  145. */
  146. //
  147. //****************************************************************************
  148. };// End namespace common
  149. };// End namespace sort
  150. };// End namespace boost
  151. //****************************************************************************
  152. //
  153. #endif