insertion_sort.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. #if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600))
  32. #pragma GCC diagnostic push
  33. #pragma GCC diagnostic ignored "-Wsign-conversion"
  34. #endif
  35. namespace boost { namespace movelib{
  36. // @cond
  37. template <class Compare, class ForwardIterator, class BirdirectionalIterator, class Op>
  38. void insertion_sort_op(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp, Op op)
  39. {
  40. if (first1 != last1){
  41. BirdirectionalIterator last2 = first2;
  42. op(first1, last2);
  43. for (++last2; ++first1 != last1; ++last2){
  44. BirdirectionalIterator j2 = last2;
  45. BirdirectionalIterator i2 = j2;
  46. if (comp(*first1, *--i2)){
  47. op(i2, j2);
  48. for (--j2; i2 != first2 && comp(*first1, *--i2); --j2) {
  49. op(i2, j2);
  50. }
  51. }
  52. op(first1, j2);
  53. }
  54. }
  55. }
  56. template <class Compare, class ForwardIterator, class BirdirectionalIterator>
  57. void insertion_sort_swap(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
  58. {
  59. insertion_sort_op(first1, last1, first2, comp, swap_op());
  60. }
  61. template <class Compare, class ForwardIterator, class BirdirectionalIterator>
  62. void insertion_sort_copy(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
  63. {
  64. insertion_sort_op(first1, last1, first2, comp, move_op());
  65. }
  66. // @endcond
  67. template <class Compare, class BirdirectionalIterator>
  68. void insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp)
  69. {
  70. typedef typename boost::movelib::iterator_traits<BirdirectionalIterator>::value_type value_type;
  71. if (first != last){
  72. BirdirectionalIterator i = first;
  73. for (++i; i != last; ++i){
  74. BirdirectionalIterator j = i;
  75. if (comp(*i, *--j)) {
  76. value_type tmp(::boost::move(*i));
  77. *i = ::boost::move(*j);
  78. for (BirdirectionalIterator k = j; k != first && comp(tmp, *--k); --j) {
  79. *j = ::boost::move(*k);
  80. }
  81. *j = ::boost::move(tmp);
  82. }
  83. }
  84. }
  85. }
  86. template <class Compare, class BirdirectionalIterator, class BirdirectionalRawIterator>
  87. void insertion_sort_uninitialized_copy
  88. (BirdirectionalIterator first1, BirdirectionalIterator const last1
  89. , BirdirectionalRawIterator const first2
  90. , Compare comp)
  91. {
  92. typedef typename iterator_traits<BirdirectionalIterator>::value_type value_type;
  93. if (first1 != last1){
  94. BirdirectionalRawIterator last2 = first2;
  95. ::new((iterator_to_raw_pointer)(last2), boost_move_new_t()) value_type(::boost::move(*first1));
  96. destruct_n<value_type, BirdirectionalRawIterator> d(first2);
  97. d.incr();
  98. for (++last2; ++first1 != last1; ++last2){
  99. BirdirectionalRawIterator j2 = last2;
  100. BirdirectionalRawIterator k2 = j2;
  101. if (comp(*first1, *--k2)){
  102. ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*k2));
  103. d.incr();
  104. for (--j2; k2 != first2 && comp(*first1, *--k2); --j2)
  105. *j2 = ::boost::move(*k2);
  106. *j2 = ::boost::move(*first1);
  107. }
  108. else{
  109. ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*first1));
  110. d.incr();
  111. }
  112. }
  113. d.release();
  114. }
  115. }
  116. }} //namespace boost { namespace movelib{
  117. #if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600))
  118. #pragma GCC diagnostic pop
  119. #endif
  120. #endif //#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP