add C++14 constexpr set/heap/permutation algorithms

This commit is contained in:
bolero-MURAKAMI 2014-04-06 18:37:06 +09:00
parent ecccb58042
commit 098dd1721e
13 changed files with 649 additions and 11 deletions

View file

@ -48,16 +48,16 @@
#include <sprout/algorithm/cxx14/nth_element.hpp>
#include <sprout/algorithm/cxx14/merge.hpp>
#include <sprout/algorithm/cxx14/inplace_merge.hpp>
//#include <sprout/algorithm/cxx14/set_union.hpp>
//#include <sprout/algorithm/cxx14/set_intersection.hpp>
//#include <sprout/algorithm/cxx14/set_difference.hpp>
//#include <sprout/algorithm/cxx14/set_symmetric_difference.hpp>
//#include <sprout/algorithm/cxx14/push_heap.hpp>
//#include <sprout/algorithm/cxx14/pop_heap.hpp>
//#include <sprout/algorithm/cxx14/make_heap.hpp>
//#include <sprout/algorithm/cxx14/sort_heap.hpp>
//#include <sprout/algorithm/cxx14/next_permutation.hpp>
//#include <sprout/algorithm/cxx14/prev_permutation.hpp>
#include <sprout/algorithm/cxx14/set_union.hpp>
#include <sprout/algorithm/cxx14/set_intersection.hpp>
#include <sprout/algorithm/cxx14/set_difference.hpp>
#include <sprout/algorithm/cxx14/set_symmetric_difference.hpp>
#include <sprout/algorithm/cxx14/push_heap.hpp>
#include <sprout/algorithm/cxx14/pop_heap.hpp>
#include <sprout/algorithm/cxx14/make_heap.hpp>
#include <sprout/algorithm/cxx14/sort_heap.hpp>
#include <sprout/algorithm/cxx14/next_permutation.hpp>
#include <sprout/algorithm/cxx14/prev_permutation.hpp>
#include <sprout/algorithm/cxx14/sample.hpp>
#include <sprout/algorithm/cxx14/copy_while.hpp>
#include <sprout/algorithm/cxx14/copy_until.hpp>

View file

@ -0,0 +1,85 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_DETAIL_HEAP_TOOL_HPP
#define SPROUT_ALGORITHM_CXX14_DETAIL_HEAP_TOOL_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/utility/move.hpp>
namespace sprout {
namespace detail {
template<typename Compare, typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
push_heap_front(
RandomAccessIterator first, RandomAccessIterator, Compare comp,
typename std::iterator_traits<RandomAccessIterator>::difference_type len
)
{
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
if (len > 1) {
difference_type p = 0;
RandomAccessIterator pp = first;
difference_type c = 2;
RandomAccessIterator cp = first + c;
if (c == len || comp(*cp, *(cp - 1))) {
--c;
--cp;
}
if (comp(*pp, *cp)) {
value_type t(sprout::move(*pp));
do {
*pp = sprout::move(*cp);
pp = cp;
p = c;
c = (p + 1) * 2;
if (c > len) {
break;
}
cp = first + c;
if (c == len || comp(*cp, *(cp - 1))) {
--c;
--cp;
}
} while (comp(t, *cp));
*pp = sprout::move(t);
}
}
}
template<typename Compare, typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
push_heap_back(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
typename std::iterator_traits<RandomAccessIterator>::difference_type len
)
{
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
if (len > 1) {
len = (len - 2) / 2;
RandomAccessIterator ptr = first + len;
if (comp(*ptr, *--last)) {
value_type t(sprout::move(*last));
do {
*last = sprout::move(*ptr);
last = ptr;
if (len == 0) {
break;
}
len = (len - 1) / 2;
ptr = first + len;
} while (comp(*ptr, t));
*last = sprout::move(t);
}
}
}
} // namespace detail
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_DETAIL_HEAP_TOOL_HPP

View file

@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_MAKE_HEAP_HPP
#define SPROUT_ALGORITHM_CXX14_MAKE_HEAP_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/detail/heap_tool.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
difference_type len = last - first;
if (len > 1) {
last = first;
++last;
for (difference_type i = 1; i < len; ++i) {
sprout::detail::push_heap_back<Compare>(first, ++last, comp, i);
}
}
}
} // namespace detail
//
// 25.4.6.3 make_heap
//
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR void
make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
sprout::detail::make_heap<compare_ref>(first, last, comp);
}
template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
make_heap(RandomAccessIterator first, RandomAccessIterator last) {
sprout::make_heap(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_MAKE_HEAP_HPP

View file

@ -0,0 +1,64 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_NEXT_PERMUTATION_HPP
#define SPROUT_ALGORITHM_CXX14_NEXT_PERMUTATION_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/reverse.hpp>
#include <sprout/utility/swap.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename BidirectionalIterator>
inline SPROUT_CXX14_CONSTEXPR bool
next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) {
BidirectionalIterator i = last;
if (first == last || first == --i) {
return false;
}
while (true) {
BidirectionalIterator ip1 = i;
if (comp(*--i, *ip1)) {
BidirectionalIterator j = last;
while (!comp(*i, *--j))
;
sprout::swap(*i, *j);
sprout::reverse(ip1, last);
return true;
}
if (i == first) {
sprout::reverse(first, last);
return false;
}
}
}
} // namespace detail
//
// 25.4.9 Permutation generators
//
template<typename BidirectionalIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR bool
next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
return sprout::detail::next_permutation<compare_ref>(first, last, comp);
}
template<typename BidirectionalIterator>
inline SPROUT_CXX14_CONSTEXPR bool
next_permutation(BidirectionalIterator first, BidirectionalIterator last) {
return sprout::next_permutation(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<BidirectionalIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_NEXT_PERMUTATION_HPP

View file

@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_POP_HEAP_HPP
#define SPROUT_ALGORITHM_CXX14_POP_HEAP_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/detail/heap_tool.hpp>
#include <sprout/utility/swap.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
pop_heap(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
typename std::iterator_traits<RandomAccessIterator>::difference_type len
)
{
if (len > 1) {
sprout::swap(*first, *--last);
sprout::detail::push_heap_front<Compare>(first, last, comp, len - 1);
}
}
} // namespace detail
//
// 25.4.6.2 pop_heap
//
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR void
pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
sprout::detail::pop_heap<compare_ref>(first, last, comp, last - first);
}
template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
sprout::pop_heap(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_POP_HEAP_HPP

View file

@ -0,0 +1,64 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_PREV_PERMUTATION_HPP
#define SPROUT_ALGORITHM_CXX14_PREV_PERMUTATION_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/reverse.hpp>
#include <sprout/utility/swap.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename BidirectionalIterator>
inline SPROUT_CXX14_CONSTEXPR bool
prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) {
BidirectionalIterator i = last;
if (first == last || first == --i) {
return false;
}
while (true) {
BidirectionalIterator ip1 = i;
if (comp(*ip1, *--i)) {
BidirectionalIterator j = last;
while (!comp(*--j, *i))
;
sprout::swap(*i, *j);
sprout::reverse(ip1, last);
return true;
}
if (i == first) {
sprout::reverse(first, last);
return false;
}
}
}
} // namespace detail
//
// 25.4.9 Permutation generators
//
template<typename BidirectionalIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR bool
prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
return sprout::detail::prev_permutation<compare_ref>(first, last, comp);
}
template<typename BidirectionalIterator>
inline SPROUT_CXX14_CONSTEXPR bool
prev_permutation(BidirectionalIterator first, BidirectionalIterator last) {
return sprout::prev_permutation(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<BidirectionalIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_PREV_PERMUTATION_HPP

View file

@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_PUSH_HEAP_HPP
#define SPROUT_ALGORITHM_CXX14_PUSH_HEAP_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/detail/heap_tool.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
//
// 25.4.6.1 push_heap
//
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR void
push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
sprout::detail::push_heap_back<compare_ref>(first, last, comp, last - first);
}
template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
push_heap(RandomAccessIterator first, RandomAccessIterator last) {
sprout::push_heap(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_PUSH_HEAP_HPP

View file

@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_SET_DIFFERENCE_HPP
#define SPROUT_ALGORITHM_CXX14_SET_DIFFERENCE_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/algorithm/cxx14/copy.hpp>
#include <sprout/functional/less.hpp>
namespace sprout {
//
// 25.4.5.4 set_difference
//
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
} else if (comp(*first2, *first1)) {
++first2;
} else {
++first1;
++first2;
}
}
return sprout::copy(first1, last1, result);
}
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) {
return sprout::set_difference(
first1, last1, first2, last2, result,
sprout::less<>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_SET_DIFFERENCE_HPP

View file

@ -0,0 +1,54 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_SET_INTERSECTION_HPP
#define SPROUT_ALGORITHM_CXX14_SET_INTERSECTION_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/functional/less.hpp>
namespace sprout {
//
// 25.4.5.3 set_intersection
//
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) {
while (first1 != last1 && first2 != last2) {
if (comp(*first1, *first2)) {
++first1;
} else if (comp(*first2, *first1)) {
++first2;
} else {
*result = *first1;
++first1;
++first2;
++result;
}
}
return result;
}
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) {
return sprout::set_intersection(
first1, last1, first2, last2, result,
sprout::less<>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_SET_INTERSECTION_HPP

View file

@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_SET_SYMMETRIC_DIFFERENCE_HPP
#define SPROUT_ALGORITHM_CXX14_SET_SYMMETRIC_DIFFERENCE_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/algorithm/cxx14/copy.hpp>
#include <sprout/functional/less.hpp>
namespace sprout {
//
// 25.4.5.5 set_symmetric_difference
//
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) {
while (true) {
if (first1 == last1) {
return std::copy(first2, last2, result);
}
if (first2 == last2) {
return std::copy(first1, last1, result);
}
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
++result;
} else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
++result;
} else {
++first1;
++first2;
}
}
}
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) {
return sprout::set_symmetric_difference(
first1, last1, first2, last2, result,
sprout::less<>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_SET_SYMMETRIC_DIFFERENCE_HPP

View file

@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_SET_UNION_HPP
#define SPROUT_ALGORITHM_CXX14_SET_UNION_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/type_traits/is_iterator_of.hpp>
#include <sprout/type_traits/enabler_if.hpp>
#include <sprout/algorithm/cxx14/copy.hpp>
#include <sprout/functional/less.hpp>
namespace sprout {
//
// 25.4.5.2 set_union
//
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp) {
while (true) {
if (first1 == last1) {
return std::copy(first2, last2, result);
}
if (first2 == last2) {
return std::copy(first1, last1, result);
}
if (comp(*first1, *first2)) {
*result = *first1;
++first1;
} else if (comp(*first2, *first1)) {
*result = *first2;
++first2;
} else {
*result = *first1;
++first1;
++first2;
}
++result;
}
}
template<
typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename sprout::enabler_if<sprout::is_iterator_outputable<OutputIterator>::value>::type = sprout::enabler
>
inline SPROUT_CXX14_CONSTEXPR OutputIterator
set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) {
return sprout::set_union(
first1, last1, first2, last2, result,
sprout::less<>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_SET_UNION_HPP

View file

@ -16,7 +16,6 @@
#include <sprout/utility/swap.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename RandomAccessIterator>

View file

@ -0,0 +1,49 @@
/*=============================================================================
Copyright (c) 2011-2014 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_ALGORITHM_CXX14_SORT_HEAP_HPP
#define SPROUT_ALGORITHM_CXX14_SORT_HEAP_HPP
#include <iterator>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/algorithm/cxx14/pop_heap.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename Compare, typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
difference_type len = last - first;
for (difference_type len = last - first; len > 1; --last, --len) {
sprout::detail::pop_heap<Compare>(first, last, comp, len);
}
}
} // namespace detail
//
// 25.4.6.4 sort_heap
//
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CXX14_CONSTEXPR void
sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
sprout::detail::sort_heap<compare_ref>(first, last, comp);
}
template<typename RandomAccessIterator>
inline SPROUT_CXX14_CONSTEXPR void
sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
sprout::sort_heap(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
);
}
} // namespace sprout
#endif // #ifndef SPROUT_ALGORITHM_CXX14_SORT_HEAP_HPP