Skip to content

Commit 9fc8bd5

Browse files
committed
Fix ReSharper/IntelliSense error
1 parent 907ecdc commit 9fc8bd5

2 files changed

Lines changed: 39 additions & 12 deletions

File tree

‎include/iris/rvariant/rvariant.hpp‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,14 @@ inline constexpr primary_construct_t primary_construct{};
150150
// being an assignment operator at all ([class.copy.assign]/1).
151151
// - A `= default` assignment operator whose constraints are not satisfied makes them declare an
152152
// implicit move assignment, and the implicit assignment operators of a derived class are
153-
// computed from it. A deleted declaration that is selected exactly when neither of the other two
154-
// is prevents this.
153+
// computed from it. An additional declaration that is selected exactly when neither of the
154+
// other two is prevents this: a deleted copy assignment, and a move assignment that forwards to
155+
// the copy assignment (or a deleted one if the copy assignment is not usable either), because
156+
// a move assignment that does not participate must fall back to the copy assignment.
155157
// Constructors and destructors are not affected.
156158
struct rvariant_not_copy_assignable { rvariant_not_copy_assignable() = delete; };
157159
struct rvariant_not_move_assignable { rvariant_not_move_assignable() = delete; };
160+
struct rvariant_not_move_assignable_fallback { rvariant_not_move_assignable_fallback() = delete; };
158161
#endif
159162

160163
template<class... Ts>
@@ -359,10 +362,29 @@ IRIS_RVARIANT_ALWAYS_THROWING_UNREACHABLE_END
359362
}
360363

361364
#if defined(__INTELLISENSE__) || defined(__RESHARPER__)
365+
constexpr rvariant& operator=(
366+
std::conditional_t<
367+
(!detail::rvariant_trivially_move_assignable<Ts...>) &&
368+
(!detail::rvariant_move_assignable<Ts...>) &&
369+
detail::rvariant_copy_assignable<Ts...>,
370+
rvariant,
371+
detail::rvariant_not_move_assignable_fallback
372+
>&& rhs
373+
)
374+
noexcept(detail::rvariant_nothrow_copy_assignable<Ts...>)
375+
requires
376+
(!detail::rvariant_trivially_move_assignable<Ts...>) &&
377+
(!detail::rvariant_move_assignable<Ts...>) &&
378+
detail::rvariant_copy_assignable<Ts...>
379+
{
380+
return *this = static_cast<rvariant const&>(rhs);
381+
}
382+
362383
constexpr rvariant& operator=(rvariant&&)
363384
requires
364385
(!detail::rvariant_trivially_move_assignable<Ts...>) &&
365-
(!detail::rvariant_move_assignable<Ts...>)
386+
(!detail::rvariant_move_assignable<Ts...>) &&
387+
(!detail::rvariant_copy_assignable<Ts...>)
366388
= delete;
367389
#endif
368390

‎test/rvariant/iris_rvariant_test.hpp‎

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,16 @@ struct MC_Thrower : detail::Thrower_base
7676
{
7777
public:
7878
using MC_Thrower::Thrower_base::Thrower_base;
79-
using MC_Thrower::Thrower_base::operator=;
79+
80+
// Not `using Thrower_base::operator=;` because IntelliSense/ReSharper's `std::is_assignable`
81+
// does not see assignment operators brought in by a using-declaration
82+
template<class Tag>
83+
requires (!std::is_same_v<Tag, MC_Thrower>) && std::is_assignable_v<Thrower_base&, Tag const&>
84+
MC_Thrower& operator=(Tag const& tag) noexcept(std::is_nothrow_assignable_v<Thrower_base&, Tag const&>)
85+
{
86+
Thrower_base::operator=(tag);
87+
return *this;
88+
}
8089

8190
MC_Thrower() noexcept : Thrower_base() {}
8291
MC_Thrower(MC_Thrower const&) noexcept : Thrower_base() {}
@@ -130,21 +139,19 @@ struct HashForwarded
130139
} // unit_test
131140

132141

133-
namespace std {
134-
135142
template<class T>
136-
struct hash<::unit_test::HashForwarded<T>>
143+
struct std::hash<::unit_test::HashForwarded<T>> // NOLINT(bugprone-std-namespace-modification)
137144
{
138-
size_t operator()(::unit_test::HashForwarded<T> const& v) const
145+
std::size_t operator()(::unit_test::HashForwarded<T> const& v) const
139146
{
140147
return std::hash<T>{}(v.value);
141148
}
142149
};
143150

144151
template<class charT>
145-
struct formatter<::unit_test::MC_Thrower, charT> // NOLINT(cert-dcl58-cpp)
152+
struct std::formatter<::unit_test::MC_Thrower, charT> // NOLINT(cert-dcl58-cpp)
146153
{
147-
static constexpr typename std::basic_format_parse_context<charT>::const_iterator
154+
static constexpr std::basic_format_parse_context<charT>::const_iterator
148155
parse(std::basic_format_parse_context<charT>& ctx)
149156
{
150157
if (ctx.begin() == ctx.end()) return ctx.begin();
@@ -159,6 +166,4 @@ struct formatter<::unit_test::MC_Thrower, charT> // NOLINT(cert-dcl58-cpp)
159166
}
160167
};
161168

162-
} // std
163-
164169
#endif

0 commit comments

Comments
 (0)