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
1111#include < mutex>
1212#include < type_traits>
1313
14+ using hpx::experimental::is_replaceable;
1415using hpx::experimental::is_replaceable_v;
1516
16- // Integral types are replaceable
17+ // Integral types are replaceable (trivially relocatable)
1718static_assert (is_replaceable_v<int >);
18- // Const types are not assignable
19+ // Const types are not assignable (thus not replaceable)
1920static_assert (!is_replaceable_v<int const >);
2021
2122// Pointer types are replaceable
2223static_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
2629static_assert (is_replaceable_v<int (*)()>);
@@ -36,7 +39,7 @@ static_assert(!is_replaceable_v<int&&>);
3639// Void types
3740static_assert (!is_replaceable_v<void >);
3841
39- // std::mutex is not move assignable
42+ // std::mutex is not move assignable, nor trivially relocatable
4043static_assert (!is_replaceable_v<std::mutex>);
4144
4245struct not_destructible
@@ -60,12 +63,32 @@ struct not_move_constructible
6063};
6164static_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
7194int main () {}
0 commit comments