123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- //----------------------------------------------------------------------------
- /// @file rearrange.hpp
- /// @brief Indirect algorithm
- ///
- /// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n
- /// Distributed under the Boost Software License, Version 1.0.\n
- /// ( See accompanying file LICENSE_1_0.txt or copy at
- /// http://www.boost.org/LICENSE_1_0.txt )
- /// @version 0.1
- ///
- /// @remarks
- //-----------------------------------------------------------------------------
- #ifndef __BOOST_SORT_COMMON_REARRANGE_HPP
- #define __BOOST_SORT_COMMON_REARRANGE_HPP
- #include <ciso646>
- #include <functional>
- #include <iterator>
- #include <type_traits>
- #include <vector>
- #include <cassert>
- #include <boost/sort/common/util/traits.hpp>
- namespace boost
- {
- namespace sort
- {
- namespace common
- {
- template<class Iter_data>
- struct filter_iterator
- {
- //-----------------------------------------------------------------------
- // Variables
- //-----------------------------------------------------------------------
- Iter_data origin;
- //-----------------------------------------------------------------------
- // Functions
- //-----------------------------------------------------------------------
- filter_iterator(Iter_data global_first): origin(global_first) { };
- size_t operator ()(Iter_data itx) const
- {
- return size_t(itx - origin);
- }
- };
- struct filter_pos
- {
- size_t operator ()(size_t pos) const { return pos; };
- };
- //
- //-----------------------------------------------------------------------------
- // function : rearrange
- /// @brief This function transform a logical sort of the elements in the index
- /// of iterators in a physical sort.
- //
- /// @param global_first : iterator to the first element of the data
- /// @param [in] index : vector of the iterators
- //-----------------------------------------------------------------------------
- template<class Iter_data, class Iter_index, class Filter_pos>
- void rearrange(Iter_data global_first, Iter_index itx_first,
- Iter_index itx_last, Filter_pos pos)
- {
- //-----------------------------------------------------------------------
- // Metaprogramming
- //-----------------------------------------------------------------------
- typedef util::value_iter<Iter_data> value_data;
- typedef util::value_iter<Iter_index> value_index;
- //-------------------------------------------------------------------------
- // Code
- //-------------------------------------------------------------------------
- assert((itx_last - itx_first) >= 0);
- size_t pos_dest, pos_src, pos_ini;
- size_t nelem = size_t(itx_last - itx_first);
- Iter_data data = global_first;
- Iter_index index = itx_first;
- pos_ini = 0;
- while (pos_ini < nelem)
- {
- while (pos_ini < nelem and pos(index[pos_ini]) == pos_ini)
- ++pos_ini;
- if (pos_ini == nelem) return;
- pos_dest = pos_src = pos_ini;
- value_data aux = std::move(data[pos_ini]);
- value_index itx_src = std::move(index[pos_ini]);
- while ((pos_src = pos(itx_src)) != pos_ini)
- {
- using std::swap;
- data[pos_dest] = std::move(data[pos_src]);
- swap(itx_src, index[pos_src]);
- pos_dest = pos_src;
- };
- data[pos_dest] = std::move(aux);
- index[pos_ini] = std::move(itx_src);
- ++pos_ini;
- };
- };
- /*
- //
- //-----------------------------------------------------------------------------
- // function : rearrange_pos
- /// @brief This function transform a logical sort of the elements in the index
- /// of iterators in a physical sort.
- //
- /// @param global_first : iterator to the first element of the data
- /// @param [in] index : vector of the iterators
- //-----------------------------------------------------------------------------
- template < class Iter_t, class Number >
- void rearrange_pos (Iter_t global_first, std::vector< Number> &index)
- {
- //-------------------------------------------------------------------------
- // METAPROGRAMMING AND DEFINITIONS
- //-------------------------------------------------------------------------
- static_assert ( std::is_integral<Number>::value, "Incompatible Types");
- typedef iter_value< Iter_t > value_t;
- //-------------------------------------------------------------------------
- // CODE
- //-------------------------------------------------------------------------
- size_t pos_dest = 0;
- size_t pos_src = 0;
- size_t pos_ini = 0;
- size_t nelem = index.size ( );
- Iter_t it_dest (global_first), it_src(global_first);
- while (pos_ini < nelem)
- {
- while (pos_ini < nelem and
- index[pos_ini] == pos_ini)
- {
- ++pos_ini;
- };
- if (pos_ini == nelem) return;
- pos_dest = pos_src = pos_ini;
- it_dest = global_first + pos_dest;
- value_t Aux = std::move (*it_dest);
- while ((pos_src = index[pos_dest]) != pos_ini)
- {
- index[pos_dest] = it_dest - global_first;
- it_src = global_first + pos_src;
- *it_dest = std::move (*it_src);
- it_dest = it_src;
- pos_dest = pos_src;
- };
- *it_dest = std::move (Aux);
- index[pos_dest] = it_dest - global_first;
- ++pos_ini;
- };
- };
- */
- //
- //****************************************************************************
- };// End namespace common
- };// End namespace sort
- };// End namespace boost
- //****************************************************************************
- //
- #endif
|