diff --git a/sprout/algorithm/fixed/make_heap.hpp b/sprout/algorithm/fixed/make_heap.hpp index 73537e28..95130ad7 100644 --- a/sprout/algorithm/fixed/make_heap.hpp +++ b/sprout/algorithm/fixed/make_heap.hpp @@ -8,10 +8,130 @@ #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::result_of::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::result_of::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::result_of::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::result_of::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 sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::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::result_of::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 sprout::throw_recursive_function_template_instantiation_exeeded(); + } +#else template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type make_heap_impl( @@ -91,6 +211,7 @@ namespace sprout { ) ; } +#endif } // namespace detail // // make_heap