Skip to content

Commit 924c8dd

Browse files
relocation traits
Signed-off-by: guptapratykshh <pratykshgupta9999@gmail.com>
1 parent 2b0d390 commit 924c8dd

3 files changed

Lines changed: 39 additions & 19 deletions

File tree

libs/core/type_support/include/hpx/type_support/is_replaceable.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010

1111
#include <type_traits>
1212

13+
#include <hpx/type_support/is_trivially_relocatable.hpp>
14+
1315
namespace hpx::experimental {
1416

1517
HPX_CXX_EXPORT template <typename T>
1618
struct is_replaceable
17-
: std::bool_constant<std::is_object_v<T> &&
18-
std::is_move_constructible_v<T> && std::is_move_assignable_v<T> &&
19-
std::is_destructible_v<T> && !std::is_volatile_v<T>>
19+
: std::bool_constant<std::is_move_constructible_v<T> &&
20+
std::is_move_assignable_v<T> && is_trivially_relocatable_v<T>>
2021
{
2122
};
2223

libs/core/type_support/include/hpx/type_support/relocate_at.hpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,10 @@ namespace hpx::experimental {
119119
// noexcept if the memmove path is taken or if the move path is noexcept
120120
noexcept(detail::relocate_at_helper(src, dst)))
121121
{
122-
#if defined(__cpp_lib_trivially_relocatable)
123-
return std::relocate_at(src, dst);
124-
#else
125-
static_assert(is_relocatable_v<T>,
126-
"new (dst) T(std::move(*src)) must be well-formed");
122+
static_assert(
123+
is_relocatable_v<T>, "T(std::move(*src)) must be well-formed");
127124

128125
return detail::relocate_at_helper(src, dst);
129-
#endif
130126
}
131127

132128
HPX_CXX_CORE_EXPORT template <typename T>

libs/core/type_support/tests/unit/is_replaceable.cpp

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2025 Isidoros Tsaousis-Seiras
1+
// Copyright (c) 2025 Pratyksh Gupta
22
//
33
// SPDX-License-Identifier: BSL-1.0
44
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -11,16 +11,19 @@
1111
#include <mutex>
1212
#include <type_traits>
1313

14+
using hpx::experimental::is_replaceable;
1415
using hpx::experimental::is_replaceable_v;
1516

16-
// Integral types are replaceable
17+
// Integral types are replaceable (trivially relocatable)
1718
static_assert(is_replaceable_v<int>);
18-
// Const types are not assignable
19+
// Const types are not assignable (thus not replaceable)
1920
static_assert(!is_replaceable_v<int const>);
2021

2122
// Pointer types are replaceable
2223
static_assert(is_replaceable_v<int*>);
23-
static_assert(is_replaceable_v<int const*>);
24+
static_assert(is_replaceable_v<int const*>); // pointer itself is mutable
25+
static_assert(
26+
!is_replaceable_v<int* const>); // const pointer is not replaceable
2427

2528
// Function pointers are replaceable
2629
static_assert(is_replaceable_v<int (*)()>);
@@ -36,7 +39,7 @@ static_assert(!is_replaceable_v<int&&>);
3639
// Void types
3740
static_assert(!is_replaceable_v<void>);
3841

39-
// std::mutex is not move assignable
42+
// std::mutex is not move assignable, nor trivially relocatable
4043
static_assert(!is_replaceable_v<std::mutex>);
4144

4245
struct not_destructible
@@ -60,12 +63,32 @@ struct not_move_constructible
6063
};
6164
static_assert(!is_replaceable_v<not_move_constructible>);
6265

63-
struct move_assignable
66+
struct move_assignable_but_not_trivially_relocatable
6467
{
65-
move_assignable(move_assignable&&);
66-
move_assignable& operator=(move_assignable&&);
67-
~move_assignable();
68+
std::unique_ptr<int> p;
69+
move_assignable_but_not_trivially_relocatable(
70+
move_assignable_but_not_trivially_relocatable&&) = default;
71+
move_assignable_but_not_trivially_relocatable& operator=(
72+
move_assignable_but_not_trivially_relocatable&&) = default;
6873
};
69-
static_assert(is_replaceable_v<move_assignable>);
74+
static_assert(!is_replaceable_v<move_assignable_but_not_trivially_relocatable>);
75+
76+
// Opt-in example
77+
struct opt_in_replaceable
78+
{
79+
std::unique_ptr<int> p;
80+
opt_in_replaceable(opt_in_replaceable&&) = default;
81+
opt_in_replaceable& operator=(opt_in_replaceable&&) = default;
82+
};
83+
84+
// Specialize is_replaceable for opt_in_replaceable
85+
namespace hpx::experimental {
86+
template <>
87+
struct is_replaceable<opt_in_replaceable> : std::true_type
88+
{
89+
};
90+
} // namespace hpx::experimental
91+
92+
static_assert(is_replaceable_v<opt_in_replaceable>);
7093

7194
int main() {}

0 commit comments

Comments
 (0)