action::stable_sort of vector broken on Clang 3.8.1 since ~last Xmas
tonyelewis opened this issue · comments
Tony E Lewis commented
This code used to compile and run under Clang 3.8.1:
#include <range/v3/all.hpp>
#include <iostream>
#include <vector>
int main() {
const std::vector<double> scores = { 3.0, 1.0, 2.0 };
std::vector<int> indices = { 0, 1, 2 };
indices |= ranges::action::stable_sort(
ranges::less{},
[&] (const int &x) { return scores[ x ]; }
);
std::cerr << ( indices | ranges::view::all ) << "\n";
}
...but since 6191722, it gives errors:
In file included from range-v3.stable-sort-prob.cpp:1:
In file included from range-v3/include/range/v3/all.hpp:19:
In file included from range-v3/include/range/v3/action.hpp:30:
range-v3/include/range/v3/action/stable_sort.hpp:73:21: error: static_assert failed "The object on which action::stable_sort operates must be a model of the ForwardRange concept."
CONCEPT_ASSERT_MSG(ForwardRange<Rng>(),
^ ~~~~~~~~~~~~~~~~~~~
range-v3/include/range/v3/utility/concepts.hpp:812:28: note: expanded from macro 'CONCEPT_ASSERT_MSG'
#define CONCEPT_ASSERT_MSG static_assert
^
range-v3/include/range/v3/utility/invoke.hpp:124:17: note: in instantiation of function template specialization 'ranges::v3::action::stable_sort_fn::operator()<ranges::v3::less &, (lambda at range-v3.stable-sort-prob.cpp:12:3), ranges::v3::ident, 42, 0>' requested here
detail::forward<F>(fn)(detail::forward<Args>(args)...)
^
In file included from range-v3.stable-sort-prob.cpp:1:
In file included from range-v3/include/range/v3/all.hpp:17:
In file included from range-v3/include/range/v3/core.hpp:18:
In file included from range-v3/include/range/v3/distance.hpp:22:
In file included from range-v3/include/range/v3/range_traits.hpp:24:
range-v3/include/range/v3/range_concepts.hpp:64:45: error: no matching function for call to object of type 'const ranges::v3::adl_begin_end_detail::begin_fn'
using iterator_t = decltype(begin(std::declval<T&>()));
^~~~~
range-v3/include/range/v3/range_traits.hpp:35:9: note: in instantiation of template type alias 'iterator_t' requested here
using range_iterator_t = concepts::Range::iterator_t<Rng>;
^
range-v3/include/range/v3/action/stable_sort.hpp:76:31: note: in instantiation of template type alias 'range_iterator_t' requested here
using I = range_iterator_t<Rng>;
^
range-v3/include/range/v3/utility/invoke.hpp:124:17: note: in instantiation of function template specialization 'ranges::v3::action::stable_sort_fn::operator()<ranges::v3::less &, (lambda at range-v3.stable-sort-prob.cpp:12:3), ranges::v3::ident, 42, 0>' requested here
detail::forward<F>(fn)(detail::forward<Args>(args)...)
^
range-v3/include/range/v3/begin_end.hpp:105:32: note: candidate template ignored: substitution failure [with Rng = ranges::v3::less &]: no matching function for call to 'impl'
constexpr auto operator()(Rng && rng) const
^
In file included from range-v3.stable-sort-prob.cpp:1:
In file included from range-v3/include/range/v3/all.hpp:19:
In file included from range-v3/include/range/v3/action.hpp:30:
range-v3/include/range/v3/action/stable_sort.hpp:77:21: error: static_assert failed "The projection function must accept objects of the iterator's value type, reference type, and common reference type."
CONCEPT_ASSERT_MSG(IndirectInvocable<P, I>(),
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
range-v3/include/range/v3/utility/concepts.hpp:812:28: note: expanded from macro 'CONCEPT_ASSERT_MSG'
#define CONCEPT_ASSERT_MSG static_assert
^
range-v3/include/range/v3/utility/invoke.hpp:124:17: note: in instantiation of function template specialization 'ranges::v3::action::stable_sort_fn::operator()<ranges::v3::less &, (lambda at range-v3.stable-sort-prob.cpp:12:3), ranges::v3::ident, 42, 0>' requested here
detail::forward<F>(fn)(detail::forward<Args>(args)...)
^
In file included from range-v3.stable-sort-prob.cpp:1:
In file included from range-v3/include/range/v3/all.hpp:17:
In file included from range-v3/include/range/v3/core.hpp:17:
In file included from range-v3/include/range/v3/begin_end.hpp:21:
In file included from range-v3/include/range/v3/range_fwd.hpp:20:
range-v3/include/meta/meta.hpp:140:9: error: no type named 'type' in 'meta::v1::detail::_if_<meta::v1::list<std::__1::integral_constant<bool, false>, ranges::v3::detail::projected_<int, ranges::v3::ident> >, bool>'
using _t = typename T::type;
^~~~~
range-v3/include/meta/meta.hpp:1110:9: note: in instantiation of template type alias '_t' requested here
using if_c = _t<detail::_if_<list<bool_<If>, Args...>>>;
^
range-v3/include/range/v3/utility/iterator_concepts.hpp:568:9: note: in instantiation of template type alias 'if_c' requested here
using projected = meta::if_c<IndirectInvocable<Proj, I>::value, detail::projected_<I, Proj>>;
^
range-v3/include/range/v3/action/stable_sort.hpp:80:60: note: in instantiation of template type alias 'projected' requested here
CONCEPT_ASSERT_MSG(IndirectRelation<C, projected<I, P>>(),
^
range-v3/include/range/v3/utility/invoke.hpp:124:17: note: in instantiation of function template specialization 'ranges::v3::action::stable_sort_fn::operator()<ranges::v3::less &, (lambda at range-v3.stable-sort-prob.cpp:12:3), ranges::v3::ident, 42, 0>' requested here
detail::forward<F>(fn)(detail::forward<Args>(args)...)
^
4 errors generated.
From what I can see on Wandbox, the problem disappears for Clang ≥ 4.0.
Tony E Lewis commented
Sorry: I forgot to say that this works without problem under GCC.
Casey Carter commented
Workaround:
-indices |= ranges::action::stable_sort(
+ranges::action::stable_sort(indices,
...which should suggest where the problem lies.
Casey Carter commented
sort-of minimized repro:
#include <range/v3/action/stable_sort.hpp>
int main() {
int ints[1] = {};
#ifndef WORKAROUND
ints |= ranges::action::stable_sort(ranges::less{});
#else
ranges::action::stable_sort(ints, ranges::less{});
#endif
}
Tony E Lewis commented
Thanks so much for this quick response and pointer on how I can work around the issue. Apologies for not having minimised further myself.
Eric Niebler commented
PR #634 should fix this.
Tony E Lewis commented
Tony E Lewis commented
This works for me. Thanks so much for all your work on this.