Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial trait definition for relocatable #6212

Merged
merged 21 commits into from May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/core/algorithms/CMakeLists.txt
Expand Up @@ -6,6 +6,7 @@

set(algorithms_headers
hpx/algorithms/traits/is_pair.hpp
hpx/algorithms/traits/is_relocatable.hpp
hpx/algorithms/traits/is_value_proxy.hpp
hpx/algorithms/traits/pointer_category.hpp
hpx/algorithms/traits/projected.hpp
Expand Down
@@ -0,0 +1,22 @@
// Copyright (c) 2023 Isidoros Tsaousis-Seiras
//
// 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 <type_traits>

namespace hpx::traits {

template <typename T>
struct is_relocatable
{
static constexpr bool value =
std::is_move_constructible_v<T> && std::is_destructible_v<T>;
};

template <typename T>
inline constexpr bool is_relocatable_v = is_relocatable<T>::value;
} // namespace hpx::traits
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <hpx/algorithms/traits/is_relocatable.hpp>
#include <hpx/iterator_support/traits/is_iterator.hpp>

#include <type_traits>
Expand All @@ -24,6 +25,10 @@ namespace hpx::traits {
{
};

struct relocatable_pointer_tag : general_pointer_tag
{
};

namespace detail {

///////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -99,14 +104,8 @@ namespace hpx::traits {
// clang-format on

template <typename Source, typename Dest,
bool NonContiguous = !iterators_are_contiguous_v<Source, Dest>>
bool Contiguous = iterators_are_contiguous_v<Source, Dest>>
struct pointer_move_category
{
using type = general_pointer_tag;
};

template <typename Source, typename Dest>
struct pointer_move_category<Source, Dest, false>
{
using type = std::conditional_t<
std::is_trivially_assignable_v<iter_reference_t<Dest>,
Expand All @@ -116,15 +115,15 @@ namespace hpx::traits {
general_pointer_tag>;
};

template <typename Source, typename Dest,
bool NonContiguous = !iterators_are_contiguous_v<Source, Dest>>
struct pointer_copy_category
template <typename Source, typename Dest>
struct pointer_move_category<Source, Dest, false>
{
using type = general_pointer_tag;
};

template <typename Source, typename Dest>
struct pointer_copy_category<Source, Dest, false>
template <typename Source, typename Dest,
bool Contiguous = iterators_are_contiguous_v<Source, Dest>>
struct pointer_copy_category
{
using type = std::conditional_t<
std::is_trivially_assignable_v<iter_reference_t<Dest>,
Expand All @@ -133,30 +132,60 @@ namespace hpx::traits {
iter_value_t<Dest>>,
general_pointer_tag>;
};

template <typename Source, typename Dest>
struct pointer_copy_category<Source, Dest, false>
{
using type = general_pointer_tag;
};

template <typename Source, typename Dest,
bool Contiguous = iterators_are_contiguous_v<Source, Dest>>
struct pointer_relocate_category
{
using type = std::conditional_t<
std::is_same_v<iter_value_t<Source>, iter_value_t<Dest>> &&
is_relocatable_v<iter_value_t<Source>>,
relocatable_pointer_tag, general_pointer_tag>;
};

template <typename Source, typename Dest>
struct pointer_relocate_category<Source, Dest, false>
{
using type = general_pointer_tag;
};
} // namespace detail

// isolate iterators that refer to contiguous trivially copyable sequences or
// which are pointers and their value_types are assignable
template <typename Source, typename Dest, typename Enable = void>
struct pointer_copy_category
struct pointer_copy_category : detail::pointer_copy_category<Source, Dest>
{
using type = typename detail::pointer_copy_category<Source, Dest>::type;
};

template <typename Source, typename Dest>
using pointer_copy_category_t =
typename pointer_copy_category<Source, Dest>::type;

template <typename Source, typename Dest, typename Enable = void>
struct pointer_move_category
struct pointer_move_category : detail::pointer_move_category<Source, Dest>
{
using type = typename detail::pointer_move_category<Source, Dest>::type;
};

template <typename Source, typename Dest>
using pointer_move_category_t =
typename pointer_move_category<Source, Dest>::type;

template <typename Source, typename Dest, typename Enable = void>
struct pointer_relocate_category
: detail::pointer_relocate_category<Source, Dest>
{
};

template <typename Source, typename Dest>
using pointer_relocate_category_t =
typename pointer_relocate_category<Source, Dest>::type;

// Allow for matching of iterator<T const> to iterator<T> while calculating
// pointer category.
template <typename Iterator, typename Enable = void>
Expand Down
Expand Up @@ -4,8 +4,8 @@
# 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)

set(tests test_low_level test_merge_four test_merge_vector test_nbits
test_range
set(tests test_is_relocatable test_low_level test_merge_four test_merge_vector
test_nbits test_range
)

foreach(test ${tests})
Expand Down
@@ -0,0 +1,70 @@
// Copyright (c) 2023 Isidoros Tsaousis-Seiras
//
// 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)

#include <hpx/algorithms/traits/is_relocatable.hpp>
#include <hpx/algorithms/traits/pointer_category.hpp>

#include <cassert>

#include <mutex>

// Integral types are relocatable
static_assert(hpx::is_relocatable_v<int>);
static_assert(hpx::is_relocatable_v<const int>);
static_assert(hpx::is_relocatable_v<int*>);
static_assert(hpx::is_relocatable_v<int (*)()>);

// Array types are not move-constructible and thus not relocatable
static_assert(!hpx::is_relocatable_v<int[]>);
static_assert(!hpx::is_relocatable_v<const int[]>);
static_assert(!hpx::is_relocatable_v<int[4]>);
static_assert(!hpx::is_relocatable_v<const int[4]>);

// Function types are not move-constructible and thus not relocatable
static_assert(!hpx::is_relocatable_v<int()>);

// Void types are not move-constructible and thus not relocatable
static_assert(!hpx::is_relocatable_v<void>);
static_assert(!hpx::is_relocatable_v<const void>);

// std::mutex is not relocatable
static_assert(!hpx::is_relocatable_v<std::mutex>);

struct NotDestructible
{
NotDestructible(const NotDestructible&);
NotDestructible(NotDestructible&&);
~NotDestructible() = delete;
};

static_assert(!hpx::is_relocatable_v<NotDestructible>);

struct NotMoveConstructible
{
NotMoveConstructible(const NotMoveConstructible&);
NotMoveConstructible(NotMoveConstructible&&) = delete;
};

static_assert(!hpx::is_relocatable_v<NotMoveConstructible>);

struct NotCopyConstructible
{
NotCopyConstructible(const NotCopyConstructible&) = delete;
NotCopyConstructible(NotCopyConstructible&&);
};

static_assert(hpx::is_relocatable_v<NotCopyConstructible>);

// reference types are relocatable
static_assert(hpx::is_relocatable_v<int&>);
static_assert(hpx::is_relocatable_v<int&&>);
static_assert(hpx::is_relocatable_v<int (&)()>);
static_assert(hpx::is_relocatable_v<std::mutex&>);
static_assert(hpx::is_relocatable_v<NotMoveConstructible&>);
static_assert(hpx::is_relocatable_v<NotCopyConstructible&>);
static_assert(hpx::is_relocatable_v<NotDestructible&>);

int main(int, char*[]) {}