/*============================================================================= Copyright (c) 2011-2019 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_FIXED_MAKE_HEAP_HPP #define SPROUT_ALGORITHM_FIXED_MAKE_HEAP_HPP #include #include #include #include #include #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT #ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE # include #endif namespace sprout { namespace fixed { namespace detail { #ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n = 0, typename sprout::container_traits::difference_type l = 1, typename sprout::container_traits::difference_type r = 2 ); template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n = 0, typename sprout::container_traits::difference_type l = 1, typename sprout::container_traits::difference_type r = 2 ); template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl_1( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n, typename sprout::container_traits::difference_type l, typename sprout::container_traits::difference_type r ) { return comp(*sprout::next(sprout::internal_begin(cont), offset + l), *sprout::next(sprout::internal_begin(cont), offset + r)) ? comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + r)) ? sprout::fixed::detail::make_heap_impl( sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + r) ), comp, offset, size, r, r * 2 + 1, r * 2 + 2 ) : sprout::deep_copy(cont) : comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + l)) ? sprout::fixed::detail::make_heap_impl( sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + l) ), comp, offset, size, l, l * 2 + 1, l * 2 + 2 ) : sprout::deep_copy(cont) ; } template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl_1( Container const&, Compare, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type ) { return sprout::throw_recursive_function_template_instantiation_exeeded(); } template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n, typename sprout::container_traits::difference_type l, typename sprout::container_traits::difference_type r ) { return r > size ? sprout::deep_copy(cont) : r == size ? comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + l)) ? sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + l) ) : sprout::deep_copy(cont) : sprout::fixed::detail::make_heap_impl_1( sprout::fixed::detail::make_heap_impl( sprout::fixed::detail::make_heap_impl(cont, comp, offset, size, l, l * 2 + 1, l * 2 + 2), comp, offset, size, r, r * 2 + 1, r * 2 + 2 ), comp, offset, size, n, l, r ) ; } template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const&, Compare, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type, typename sprout::container_traits::difference_type ) { return sprout::throw_recursive_function_template_instantiation_exeeded(); } #else template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n = 0, typename sprout::container_traits::difference_type l = 1, typename sprout::container_traits::difference_type r = 2 ); template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl_1( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n, typename sprout::container_traits::difference_type l, typename sprout::container_traits::difference_type r ) { return comp(*sprout::next(sprout::internal_begin(cont), offset + l), *sprout::next(sprout::internal_begin(cont), offset + r)) ? comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + r)) ? sprout::fixed::detail::make_heap_impl( sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + r) ), comp, offset, size, r, r * 2 + 1, r * 2 + 2 ) : sprout::deep_copy(cont) : comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + l)) ? sprout::fixed::detail::make_heap_impl( sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + l) ), comp, offset, size, l, l * 2 + 1, l * 2 + 2 ) : sprout::deep_copy(cont) ; } template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap_impl( Container const& cont, Compare comp, typename sprout::container_traits::difference_type offset, typename sprout::container_traits::difference_type size, typename sprout::container_traits::difference_type n, typename sprout::container_traits::difference_type l, typename sprout::container_traits::difference_type r ) { return r > size ? sprout::deep_copy(cont) : r == size ? comp(*sprout::next(sprout::internal_begin(cont), offset + n), *sprout::next(sprout::internal_begin(cont), offset + l)) ? sprout::fixed::swap_element( cont, sprout::next(sprout::internal_begin(cont), offset + n), sprout::next(sprout::internal_begin(cont), offset + l) ) : sprout::deep_copy(cont) : sprout::fixed::detail::make_heap_impl_1( sprout::fixed::detail::make_heap_impl( sprout::fixed::detail::make_heap_impl(cont, comp, offset, size, l, l * 2 + 1, l * 2 + 2), comp, offset, size, r, r * 2 + 1, r * 2 + 2 ), comp, offset, size, n, l, r ) ; } #endif } // namespace detail // // make_heap // template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap(Container const& cont, Compare comp) { return sprout::fixed::detail::make_heap_impl( cont, comp, sprout::internal_begin_offset(cont), sprout::size(cont) ); } template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type make_heap(Container const& cont) { return sprout::fixed::detail::make_heap_impl( cont, NS_SSCRISK_CEL_OR_SPROUT::less::value_type>(), sprout::internal_begin_offset(cont), sprout::size(cont) ); } } // namespace fixed using sprout::fixed::make_heap; } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_FIXED_MAKE_HEAP_HPP