insertion_sort.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2014.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // See http://www.boost.org/libs/move for documentation.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. //! \file
  12. #ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP
  13. #define BOOST_MOVE_DETAIL_INSERT_SORT_HPP
  14. #ifndef BOOST_CONFIG_HPP
  15. # include <boost/config.hpp>
  16. #endif
  17. #
  18. #if defined(BOOST_HAS_PRAGMA_ONCE)
  19. # pragma once
  20. #endif
  21. #include <boost/move/utility_core.hpp>
  22. #include <boost/move/algo/move.hpp>
  23. #include <boost/move/detail/iterator_traits.hpp>
  24. #include <boost/move/adl_move_swap.hpp>
  25. #include <boost/move/utility_core.hpp>
  26. #include <boost/move/detail/placement_new.hpp>
  27. #include <boost/move/detail/destruct_n.hpp>
  28. #include <boost/move/algo/detail/basic_op.hpp>
  29. #include <boost/move/detail/placement_new.hpp>
  30. #include <boost/move/detail/iterator_to_raw_pointer.hpp>
  31. namespace boost { namespace movelib{
  32. // @cond
  33. template <class Compare, class ForwardIterator, class BirdirectionalIterator, class Op>
  34. void insertion_sort_op(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp, Op op)
  35. {
  36. if (first1 != last1){
  37. BirdirectionalIterator last2 = first2;
  38. op(first1, last2);
  39. for (++last2; ++first1 != last1; ++last2){
  40. BirdirectionalIterator j2 = last2;
  41. BirdirectionalIterator i2 = j2;
  42. if (comp(*first1, *--i2)){
  43. op(i2, j2);
  44. for (--j2; i2 != first2 && comp(*first1, *--i2); --j2) {
  45. op(i2, j2);
  46. }
  47. }
  48. op(first1, j2);
  49. }
  50. }
  51. }
  52. template <class Compare, class ForwardIterator, class BirdirectionalIterator>
  53. void insertion_sort_swap(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
  54. {
  55. insertion_sort_op(first1, last1, first2, comp, swap_op());
  56. }
  57. template <class Compare, class ForwardIterator, class BirdirectionalIterator>
  58. void insertion_sort_copy(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
  59. {
  60. insertion_sort_op(first1, last1, first2, comp, move_op());
  61. }
  62. // @endcond
  63. template <class Compare, class BirdirectionalIterator>
  64. void insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp)
  65. {
  66. typedef typename boost::movelib::iterator_traits<BirdirectionalIterator>::value_type value_type;
  67. if (first != last){
  68. BirdirectionalIterator i = first;
  69. for (++i; i != last; ++i){
  70. BirdirectionalIterator j = i;
  71. if (comp(*i, *--j)) {
  72. value_type tmp(::boost::move(*i));
  73. *i = ::boost::move(*j);
  74. for (BirdirectionalIterator k = j; k != first && comp(tmp, *--k); --j) {
  75. *j = ::boost::move(*k);
  76. }
  77. *j = ::boost::move(tmp);
  78. }
  79. }
  80. }
  81. }
  82. template <class Compare, class BirdirectionalIterator, class BirdirectionalRawIterator>
  83. void insertion_sort_uninitialized_copy
  84. (BirdirectionalIterator first1, BirdirectionalIterator const last1
  85. , BirdirectionalRawIterator const first2
  86. , Compare comp)
  87. {
  88. typedef typename iterator_traits<BirdirectionalIterator>::value_type value_type;
  89. if (first1 != last1){
  90. BirdirectionalRawIterator last2 = first2;
  91. ::new((iterator_to_raw_pointer)(last2), boost_move_new_t()) value_type(::boost::move(*first1));
  92. destruct_n<value_type, BirdirectionalRawIterator> d(first2);
  93. d.incr();
  94. for (++last2; ++first1 != last1; ++last2){
  95. BirdirectionalRawIterator j2 = last2;
  96. BirdirectionalRawIterator k2 = j2;
  97. if (comp(*first1, *--k2)){
  98. ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*k2));
  99. d.incr();
  100. for (--j2; k2 != first2 && comp(*first1, *--k2); --j2)
  101. *j2 = ::boost::move(*k2);
  102. *j2 = ::boost::move(*first1);
  103. }
  104. else{
  105. ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*first1));
  106. d.incr();
  107. }
  108. }
  109. d.release();
  110. }
  111. }
  112. }} //namespace boost { namespace movelib{
  113. #endif //#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP