Skip to content

Commit

Permalink
Unify predicates in namespace ranges.
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Aug 6, 2020
1 parent 889e9b7 commit 4498496
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 49 deletions.
Expand Up @@ -215,6 +215,7 @@ namespace hpx { namespace ranges {

#include <hpx/algorithms/traits/projected.hpp>
#include <hpx/algorithms/traits/projected_range.hpp>
#include <hpx/execution/algorithms/detail/predicates.hpp>
#include <hpx/parallel/algorithms/equal.hpp>
#include <hpx/parallel/util/invoke_projected.hpp>
#include <hpx/parallel/util/projection_identity.hpp>
Expand All @@ -224,8 +225,6 @@ namespace hpx { namespace ranges {

namespace hpx { namespace ranges {

using equal_to = hpx::parallel::v1::detail::equal_to;

///////////////////////////////////////////////////////////////////////////
// CPO for hpx::equal
HPX_INLINE_CONSTEXPR_VARIABLE struct equal_t final
Expand Down
Expand Up @@ -217,6 +217,7 @@ namespace hpx { namespace ranges {

#include <hpx/algorithms/traits/projected.hpp>
#include <hpx/algorithms/traits/projected_range.hpp>
#include <hpx/execution/algorithms/detail/predicates.hpp>
#include <hpx/parallel/algorithms/mismatch.hpp>
#include <hpx/parallel/util/invoke_projected.hpp>
#include <hpx/parallel/util/projection_identity.hpp>
Expand All @@ -228,8 +229,6 @@ namespace hpx { namespace ranges {
namespace hpx { namespace ranges {

///////////////////////////////////////////////////////////////////////////
using equal_to = hpx::parallel::v1::detail::equal_to;

template <typename Iter1, typename Iter2>
using mismatch_result = hpx::parallel::util::in_in_result<Iter1, Iter2>;

Expand Down
Expand Up @@ -10,6 +10,7 @@
#include <hpx/assert.hpp>
#include <hpx/functional/invoke.hpp>
#include <hpx/iterator_support/traits/is_iterator.hpp>
#include <hpx/type_support/equality.hpp>

#include <hpx/execution/algorithms/detail/is_negative.hpp>

Expand Down Expand Up @@ -268,14 +269,28 @@ namespace hpx { namespace parallel { inline namespace v1 { namespace detail {
///////////////////////////////////////////////////////////////////////////
struct equal_to
{
template <typename T1, typename T2>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr auto operator()(
T1 const& t1, T2 const& t2) const -> decltype(t1 == t2)
template <typename T1, typename T2,
typename Enable = typename std::enable_if<
hpx::traits::is_equality_comparable_with<T1, T2>::value>::type>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return t1 == t2;
}
};

struct not_equal_to
{
template <typename T1, typename T2,
typename Enable = typename std::enable_if<
hpx::traits::is_equality_comparable_with<T1, T2>::value>::type>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return t1 != t2;
}
};

template <typename Value>
struct compare_to
{
Expand All @@ -302,10 +317,40 @@ namespace hpx { namespace parallel { inline namespace v1 { namespace detail {
struct less
{
template <typename T1, typename T2>
constexpr auto operator()(T1 const& t1, T2 const& t2) const
-> decltype(t1 < t2)
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return t1 < t2;
return std::forward<T1>(t1) < std::forward<T2>(t2);
}
};

struct greater
{
template <typename T1, typename T2>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return std::forward<T1>(t1) > std::forward<T2>(t2);
}
};

struct greater_equal
{
template <typename T1, typename T2>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return std::forward<T1>(t1) >= std::forward<T2>(t2);
}
};

struct less_equal
{
template <typename T1, typename T2>
HPX_HOST_DEVICE HPX_FORCEINLINE constexpr bool operator()(
T1&& t1, T2&& t2) const
{
return std::forward<T1>(t1) <= std::forward<T2>(t2);
}
};

Expand Down Expand Up @@ -370,3 +415,14 @@ namespace hpx { namespace parallel { inline namespace v1 { namespace detail {
}
};
}}}} // namespace hpx::parallel::v1::detail

namespace hpx { namespace ranges {

///////////////////////////////////////////////////////////////////////////
using equal_to = hpx::parallel::v1::detail::equal_to;
using not_equal_to = hpx::parallel::v1::detail::not_equal_to;
using less = hpx::parallel::v1::detail::less;
using greater = hpx::parallel::v1::detail::greater;
using greater_equal = hpx::parallel::v1::detail::greater_equal;
using less_equal = hpx::parallel::v1::detail::less_equal;
}} // namespace hpx::ranges
Expand Up @@ -9,6 +9,7 @@

#include <hpx/config.hpp>
#include <hpx/type_support/always_void.hpp>
#include <hpx/type_support/equality.hpp>

#include <boost/iterator/iterator_categories.hpp>

Expand Down Expand Up @@ -71,34 +72,6 @@ namespace hpx { namespace traits {
using type = decltype(*(std::declval<T&>()));
};

template <typename T, typename U, typename Enable = void>
struct equality_result
{
};

template <typename T, typename U>
struct equality_result<T, U,
typename util::always_void<decltype(
std::declval<const T&>() == std::declval<const U&>())>::type>
{
using type =
decltype(std::declval<const T&>() == std::declval<const U&>());
};

template <typename T, typename U, typename Enable = void>
struct inequality_result
{
};

template <typename T, typename U>
struct inequality_result<T, U,
typename util::always_void<decltype(
std::declval<const T&>() != std::declval<const U&>())>::type>
{
using type =
decltype(std::declval<const T&>() != std::declval<const U&>());
};

template <typename T, typename U, typename Enable = void>
struct inplace_addition_result
{
Expand Down
Expand Up @@ -12,30 +12,27 @@
#include <type_traits>
#include <utility>

// The trait checks whether sentinel Sent is proper for iterator I.
// There are two requirements for this:
// 1. iterator I should be an input or output iterator
// 2. I and S should oblige with the weakly-equality-comparable concept

namespace hpx { namespace traits {

///////////////////////////////////////////////////////////////////////////
// The trait checks whether sentinel Sent is proper for iterator I.
// There are two requirements for this:
// 1. iterator I should be an input or output iterator
// 2. I and S should oblige with the weakly-equality-comparable concept
template <typename Sent, typename Iter, typename Enable = void>
struct is_sentinel_for : std::false_type
{
};

template <typename Sent, typename Iter>
struct is_sentinel_for<Sent, Iter,
typename util::always_void<
typename std::enable_if<is_iterator<Iter>::value>::type,
typename detail::equality_result<Iter, Sent>::type,
typename detail::equality_result<Sent, Iter>::type,
typename detail::inequality_result<Iter, Sent>::type,
typename detail::inequality_result<Sent, Iter>::type>::type>
typename std::enable_if<is_iterator<Iter>::value &&
is_weakly_equality_comparable_with<Iter, Sent>::value>::type>
: std::true_type
{
};

///////////////////////////////////////////////////////////////////////////
#if defined(HPX_HAVE_CXX20_STD_DISABLE_SIZED_SENTINEL_FOR)
template <typename Sent, typename Iter>
inline constexpr bool disable_sized_sentinel_for =
Expand Down
1 change: 1 addition & 0 deletions libs/type_support/CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ set(type_support_headers
hpx/type_support/always_void.hpp
hpx/type_support/decay.hpp
hpx/type_support/detected.hpp
hpx/type_support/equality.hpp
hpx/type_support/identity.hpp
hpx/type_support/lazy_conditional.hpp
hpx/type_support/lazy_enable_if.hpp
Expand Down
82 changes: 82 additions & 0 deletions libs/type_support/include/hpx/type_support/equality.hpp
@@ -0,0 +1,82 @@
// Copyright (c) 2007-2020 Hartmut Kaiser
// Copyright (c) 2019 Austin McCartney
//
// SPDX-License-Identifier: BSL-1.0
// 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)

#pragma once

#include <hpx/config.hpp>
#include <hpx/type_support/always_void.hpp>

#include <type_traits>
#include <utility>

namespace hpx { namespace traits {
namespace detail {

///////////////////////////////////////////////////////////////////////
template <typename T, typename U, typename Enable = void>
struct equality_result
{
};

template <typename T, typename U>
struct equality_result<T, U,
typename util::always_void<decltype(
std::declval<const T&>() == std::declval<const U&>())>::type>
{
using type =
decltype(std::declval<const T&>() == std::declval<const U&>());
};

///////////////////////////////////////////////////////////////////////
template <typename T, typename U, typename Enable = void>
struct inequality_result
{
};

template <typename T, typename U>
struct inequality_result<T, U,
typename util::always_void<decltype(
std::declval<const T&>() != std::declval<const U&>())>::type>
{
using type =
decltype(std::declval<const T&>() != std::declval<const U&>());
};

///////////////////////////////////////////////////////////////////////
template <typename T, typename U, typename Enable = void>
struct is_weakly_equality_comparable_with : std::false_type
{
};

template <typename T, typename U>
struct is_weakly_equality_comparable_with<T, U,
typename util::always_void<
typename detail::equality_result<T, U>::type,
typename detail::equality_result<U, T>::type,
typename detail::inequality_result<T, U>::type,
typename detail::inequality_result<U, T>::type>::type>
: std::true_type
{
};

} // namespace detail

template <typename T, typename U>
struct is_weakly_equality_comparable_with
: detail::is_weakly_equality_comparable_with<typename std::decay<T>::type,
typename std::decay<U>::type>
{
};

// for now is_equality_comparable is equivalent to its weak version
template <typename T, typename U>
struct is_equality_comparable_with
: detail::is_weakly_equality_comparable_with<typename std::decay<T>::type,
typename std::decay<U>::type>
{
};
}} // namespace hpx::traits

0 comments on commit 4498496

Please sign in to comment.