From b03da047a8a95cb7ab93769b3206772887a0eb7d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 25 Feb 2017 18:50:13 +0100 Subject: [PATCH] [index] Add workaround for libstdc++ bug (gcc 4.8.2) - segfault in nth_element. --- .../index/detail/algorithms/nth_element.hpp | 62 +++++++++++++++++++ .../index/detail/rtree/pack_create.hpp | 5 +- .../detail/rtree/rstar/choose_next_node.hpp | 5 +- .../rtree/rstar/redistribute_elements.hpp | 12 ++-- 4 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 include/boost/geometry/index/detail/algorithms/nth_element.hpp diff --git a/include/boost/geometry/index/detail/algorithms/nth_element.hpp b/include/boost/geometry/index/detail/algorithms/nth_element.hpp new file mode 100644 index 000000000..201180ae3 --- /dev/null +++ b/include/boost/geometry/index/detail/algorithms/nth_element.hpp @@ -0,0 +1,62 @@ +// Boost.Geometry Index +// +// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// +// Use, modification and distribution is subject to 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 BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP + +#include + +namespace boost { namespace geometry { namespace index { namespace detail { + +// See https://svn.boost.org/trac/boost/ticket/12861 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800 +// https://gcc.gnu.org/develop.html#timeline +// 20120920 4.7.2 - no bug +// 20130322 4.8.0 - no bug +// 20130411 4.7.3 - no bug +// 20130531 4.8.1 - no bug +// 20131016 4.8.2 - bug +// 20140422 4.9.0 - fixed +// 20140522 4.8.3 - fixed +// 20140612 4.7.4 - fixed +// 20140716 4.9.1 - fixed +#if defined(__GLIBCXX__) && (__GLIBCXX__ == 20131016) + +#warning "std::nth_element replaced with std::sort, libstdc++ bug workaround."; + +template +void nth_element(RandomIt first, RandomIt , RandomIt last) +{ + std::sort(first, last); +} + +template +void nth_element(RandomIt first, RandomIt , RandomIt last, Compare comp) +{ + std::sort(first, last, comp); +} + +#else + +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last) +{ + std::nth_element(first, nth, last); +} + +template +void nth_element(RandomIt first, RandomIt nth, RandomIt last, Compare comp) +{ + std::nth_element(first, nth, last, comp); +} + +#endif + +}}}} // namespace boost::geometry::index::detail + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_NTH_ELEMENT_HPP diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index d1491b8d4..2d3903a7b 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -2,7 +2,7 @@ // // R-tree initial packing // -// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -13,6 +13,7 @@ #include #include +#include #include @@ -67,7 +68,7 @@ struct nth_element_and_half_boxes { if ( I == dim_index ) { - std::nth_element(first, median, last, point_entries_comparer()); + index::detail::nth_element(first, median, last, point_entries_comparer()); geometry::convert(box, left); geometry::convert(box, right); diff --git a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp index 7a96986a2..89697b594 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/choose_next_node.hpp @@ -2,7 +2,7 @@ // // R-tree R*-tree next node choosing algorithm implementation // -// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -112,7 +113,7 @@ private: first_n_children_count = overlap_cost_threshold; // rearrange by content_diff // in order to calculate nearly minimum overlap cost - std::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less); + index::detail::nth_element(children_contents.begin(), children_contents.begin() + first_n_children_count, children_contents.end(), content_diff_less); } // calculate minimum or nearly minimum overlap cost diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 8f270537f..187d37fac 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -2,7 +2,7 @@ // // R-tree R*-tree split algorithm implementation // -// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -12,8 +12,9 @@ #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_REDISTRIBUTE_ELEMENTS_HPP #include -#include #include +#include +#include #include @@ -122,8 +123,9 @@ struct choose_split_axis_and_index_for_corner // { // typename Elements::iterator f = elements_copy.begin() + index_first; // typename Elements::iterator l = elements_copy.begin() + index_last; -// std::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) -// std::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) +// // NOTE: for stdlibc++ shipped with gcc 4.8.2 std::nth_element is replaced with std::sort anyway +// index::detail::nth_element(elements_copy.begin(), f, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) +// index::detail::nth_element(f, l, elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) // std::sort(f, l, elements_less); // MAY THROW, BASIC (copy) // } @@ -349,7 +351,7 @@ struct nth_element typedef typename tag::type indexable_tag; element_axis_corner_less less(tr); - std::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) + index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) } } };