Skip to content

Commit

Permalink
add indirect_result_of_t, stop using IndirectCallableRelation with T …
Browse files Browse the repository at this point in the history
…const* hack in algorithm constraints
  • Loading branch information
ericniebler committed Oct 21, 2016
1 parent 002aa1e commit 5ae0a14
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 30 deletions.
4 changes: 2 additions & 2 deletions include/range/v3/algorithm/count.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace ranges
{
template<typename I, typename S, typename V, typename P = ident,
CONCEPT_REQUIRES_(InputIterator<I>() && Sentinel<S, I>() &&
IndirectCallableRelation<equal_to, projected<I, P>, V const *>())>
Relation<equal_to, indirect_result_of_t<P &(I)>, V const &>())>
iterator_difference_t<I>
operator()(I begin, S end, V const & val, P proj_ = P{}) const
{
Expand All @@ -48,7 +48,7 @@ namespace ranges
template<typename Rng, typename V, typename P = ident,
typename I = range_iterator_t<Rng>,
CONCEPT_REQUIRES_(InputRange<Rng>() &&
IndirectCallableRelation<equal_to, projected<I, P>, V const *>())>
Relation<equal_to, indirect_result_of_t<P &(I)>, V const &>())>
iterator_difference_t<I>
operator()(Rng &&rng, V const & val, P proj = P{}) const
{
Expand Down
4 changes: 2 additions & 2 deletions include/range/v3/algorithm/find.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace ranges
/// \pre The ResultType of `P` is EqualityComparable with V
template<typename I, typename S, typename V, typename P = ident,
CONCEPT_REQUIRES_(InputIterator<I>() && Sentinel<S, I>() &&
IndirectCallableRelation<equal_to, projected<I, P>, V const *>())>
Relation<equal_to, indirect_result_of_t<P &(I)>, V const &>())>
I operator()(I begin, S end, V const &val, P proj_ = P{}) const
{
auto &&proj = as_function(proj_);
Expand All @@ -56,7 +56,7 @@ namespace ranges
template<typename Rng, typename V, typename P = ident,
typename I = range_iterator_t<Rng>,
CONCEPT_REQUIRES_(InputRange<Rng>() &&
IndirectCallableRelation<equal_to, projected<I, P>, V const *>())>
Relation<equal_to, indirect_result_of_t<P &(I)>, V const &>())>
range_safe_iterator_t<Rng> operator()(Rng &&rng, V const &val, P proj = P{}) const
{
return (*this)(begin(rng), end(rng), val, std::move(proj));
Expand Down
5 changes: 2 additions & 3 deletions include/range/v3/algorithm/max.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ namespace ranges
}

template<typename T, typename C = ordered_less, typename P = ident,
CONCEPT_REQUIRES_(
IndirectCallableRelation<C, projected<const T *, P>>())>
constexpr const T& operator()(const T &a, const T &b, C pred = C{}, P proj = P{}) const
CONCEPT_REQUIRES_(Relation<C, result_of_t<P &(T const &)>>())>
constexpr const T& operator()(T const &a, T const &b, C pred = C{}, P proj = P{}) const
{
return max2_impl(a, b, as_function(pred), as_function(proj));
}
Expand Down
5 changes: 2 additions & 3 deletions include/range/v3/algorithm/min.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ namespace ranges
}

template<typename T, typename C = ordered_less, typename P = ident,
CONCEPT_REQUIRES_(
IndirectCallableRelation<C, projected<const T *, P>>())>
constexpr const T& operator()(const T &a, const T &b, C pred = C{}, P proj = P{}) const
CONCEPT_REQUIRES_(Relation<C, result_of_t<P &(T const &)>>())>
constexpr const T& operator()(T const &a, T const &b, C pred = C{}, P proj = P{}) const
{
return min2_impl(a, b, as_function(pred), as_function(proj));
}
Expand Down
6 changes: 3 additions & 3 deletions include/range/v3/algorithm/minmax.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ namespace ranges
}

template<typename T, typename C = ordered_less, typename P = ident,
CONCEPT_REQUIRES_(
IndirectCallableRelation<C, projected<const T *, P>>())>
constexpr const T& operator()(const T &a, const T &b, C pred = C{}, P proj = P{}) const
CONCEPT_REQUIRES_(Relation<C, result_of_t<P &(T const &)>>())>
constexpr tagged_pair<tag::min(T const &), tag::max(T const &)>
operator()(const T &a, const T &b, C pred = C{}, P proj = P{}) const
{
return minmax2_impl(a, b, as_function(pred), as_function(proj));
}
Expand Down
2 changes: 1 addition & 1 deletion include/range/v3/algorithm/remove.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace ranges
template<typename I, typename T, typename P = ident>
using Removable = meta::strict_and<
ForwardIterator<I>,
IndirectCallableRelation<equal_to, projected<I, P>, T const *>,
Relation<equal_to, indirect_result_of_t<P &(I)>, T const &>,
Permutable<I>>;

/// \addtogroup group-algorithms
Expand Down
2 changes: 1 addition & 1 deletion include/range/v3/algorithm/remove_copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace ranges
using RemoveCopyable = meta::strict_and<
InputIterator<I>,
WeaklyIncrementable<O>,
IndirectCallableRelation<equal_to, projected<I, P>, T const *>,
Relation<equal_to, indirect_result_of_t<P &(I)>, T const &>,
IndirectlyCopyable<I, O>>;

/// \addtogroup group-algorithms
Expand Down
2 changes: 1 addition & 1 deletion include/range/v3/algorithm/replace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace ranges
template<typename I, typename T0, typename T1, typename P = ident>
using Replaceable = meta::strict_and<
InputIterator<I>,
IndirectCallableRelation<equal_to, projected<I, P>, T0 const *>,
Relation<equal_to, indirect_result_of_t<P &(I)>, T0 const &>,
Writable<I, T1 const &>>;

/// \addtogroup group-algorithms
Expand Down
2 changes: 1 addition & 1 deletion include/range/v3/algorithm/replace_copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace ranges
InputIterator<I>,
OutputIterator<O, T1 const &>,
IndirectlyCopyable<I, O>,
IndirectCallableRelation<equal_to, projected<I, P>, T0 const *>>;
Relation<equal_to, indirect_result_of_t<P &(I)>, T0 const &>>;

/// \addtogroup group-algorithms
/// @{
Expand Down
2 changes: 1 addition & 1 deletion include/range/v3/algorithm/search_n.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ namespace ranges
template<typename I, typename V, typename C = equal_to, typename P = ident>
using Searchnable = meta::strict_and<
ForwardIterator<I>,
IndirectCallableRelation<C, projected<I, P>, V const *>>;
Relation<C, indirect_result_of_t<P &(I)>, V const &>>;

/// \addtogroup group-algorithms
/// @{
Expand Down
49 changes: 37 additions & 12 deletions include/range/v3/utility/iterator_concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ namespace ranges
// through the CommonReference concept.
concepts::model_of<CommonReference, reference_t<I> &&, value_t<I> &>(),
concepts::model_of<CommonReference, reference_t<I> &&, rvalue_reference_t<I> &&>(),
concepts::model_of<CommonReference, rvalue_reference_t<I> &&, value_t<I> const &>(),
// Experimental additional tests. If nothing else, this is a good workout
// for the common_reference code.
concepts::model_of<Same, ranges::common_reference_t<reference_t<I>, value_t<I>>, value_t<I>>(),
concepts::model_of<Same, ranges::common_reference_t<rvalue_reference_t<I>, value_t<I>>, value_t<I>>()
concepts::model_of<CommonReference, rvalue_reference_t<I> &&, value_t<I> const &>()
// // Experimental additional tests. If nothing else, this is a good workout
// // for the common_reference code.
// concepts::model_of<Same, ranges::common_reference_t<reference_t<I>, value_t<I>>, value_t<I>>(),
// concepts::model_of<Same, ranges::common_reference_t<rvalue_reference_t<I>, value_t<I>>, value_t<I>>()
));
};

Expand Down Expand Up @@ -536,25 +536,50 @@ namespace ranges
template<typename C, typename I0, typename I1 = I0>
using IndirectCallableRelation = IndirectRelation<function_type<C>, I0, I1>;

////////////////////////////////////////////////////////////////////////////////////////////
// indirect_result_of
/// \cond
namespace detail
{
template<typename Sig, typename = void>
struct indirect_result_of_
{
};

template<typename Fun, typename... Is>
struct indirect_result_of_<
Fun(Is...),
meta::if_c<meta::strict_and<Readable<Is>...>::value>>
: meta::if_<
IndirectCallable<Fun, Is...>,
std::result_of<Fun(concepts::Readable::reference_t<Is>...)>>
{
};
}

template<typename Sig>
using indirect_result_of = detail::indirect_result_of_<Sig>;

template<typename Sig>
using indirect_result_of_t = meta::_t<detail::indirect_result_of_<Sig>>;

////////////////////////////////////////////////////////////////////////////////////////////
// Project struct, for "projecting" a Readable with a unary callable
/// \cond
namespace detail
{
template<typename I, typename Proj>
struct projected_readable
struct projected_
{
using value_type =
decay_t<concepts::Callable::result_t<Proj &, concepts::Readable::value_t<I>>>;
using reference =
concepts::Callable::result_t<Proj &, concepts::Readable::reference_t<I>>;
using reference = indirect_result_of_t<Proj &(I)>;
using value_type = decay_t<reference>;
reference operator*() const;
};
}
/// \endcond

template<typename I, typename Proj>
using projected = meta::if_<IndirectCallable<Proj, I>, detail::projected_readable<I, Proj>>;
using projected = meta::if_c<IndirectCallable<Proj, I>::value, detail::projected_<I, Proj>>;

////////////////////////////////////////////////////////////////////////////////////////////
// Composite concepts for use defining algorithms:
Expand Down Expand Up @@ -593,7 +618,7 @@ namespace ranges
template<typename I, typename V2, typename C = ordered_less, typename P = ident>
using BinarySearchable = meta::strict_and<
ForwardIterator<I>,
IndirectCallableRelation<C, projected<I, P>, V2 const *>>;
Relation<C, indirect_result_of_t<P &(I)>, V2 const &>>;

template<typename I1, typename I2, typename C = equal_to, typename P1 = ident,
typename P2 = ident>
Expand Down
6 changes: 6 additions & 0 deletions test/algorithm/find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
//===----------------------------------------------------------------------===//

#include <utility>
#include <vector>
#include <range/v3/core.hpp>
#include <range/v3/algorithm/find.hpp>
#include "../simple_test.hpp"
Expand Down Expand Up @@ -65,5 +66,10 @@ int main()
ps = find(sa, 10, &S::i_);
CHECK(ps == end(sa));

// https://github.com/Microsoft/Range-V3-VS2015/issues/9
auto vec = std::vector<std::string>{{"a"}, {"b"}, {"c"}};
auto it = ranges::find(vec, "b");
CHECK(it == vec.begin() + 1);

return ::test_result();
}

0 comments on commit 5ae0a14

Please sign in to comment.