Skip to content

Commit

Permalink
Cosmetics: given pairs of overloads for const T& and T&&, when `T…
Browse files Browse the repository at this point in the history
…` is

specified explicitly rather than inferred and when it can itself be a reference,
arrange for the first overload to be excluded for rvalue references, and for the
second one to be excluded for lvalue references.

This used to be done by the `T&&` overload handling both lvalue and rvalue
references.

For lvalue references it is crucial to exclude one of the overloads, because
they collapse to the same signature. Handling lvalue references by `const T&` is
more elegant than by `T&&`, because it matches how they work for `T` being a
non-reference, and because otherwise we need to remember to use `std::forward()`
in the `T&&` overload, even in case when this is not a function templatized over
`T` but a regular member function of a class templatized over `T`.

For rvalue references it is still nice to exclude the `const T&` overload,
because it should never be taken anyway when the other overload is a better
match.

PiperOrigin-RevId: 605621946
  • Loading branch information
QrczakMK committed Feb 9, 2024
1 parent cc1f7b2 commit 2058690
Showing 1 changed file with 31 additions and 17 deletions.
48 changes: 31 additions & 17 deletions riegeli/base/any_dependency.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,14 +434,17 @@ class
template <typename Manager,
std::enable_if_t<
absl::conjunction<
absl::negation<std::is_reference<Manager>>,
absl::negation<std::is_rvalue_reference<Manager>>,
absl::negation<any_dependency_internal::IsAnyDependency<
Ptr, Manager>>>::value,
int> = 0>
void Initialize(const Manager& manager);
template <typename Manager,
std::enable_if_t<
!any_dependency_internal::IsAnyDependency<Ptr, Manager>::value,
absl::conjunction<
absl::negation<std::is_lvalue_reference<Manager>>,
absl::negation<any_dependency_internal::IsAnyDependency<
Ptr, Manager>>>::value,
int> = 0>
void Initialize(Manager&& manager);
template <typename Manager,
Expand Down Expand Up @@ -870,16 +873,19 @@ template <typename Ptr, size_t inline_size, size_t inline_align,
struct MethodsFor {
static const Methods<Ptr> methods;

template <
typename DependentManager = Manager,
std::enable_if_t<!std::is_reference<DependentManager>::value, int> = 0>
template <typename DependentManager = Manager,
std::enable_if_t<!std::is_rvalue_reference<DependentManager>::value,
int> = 0>
static void Construct(Storage self, Ptr* self_ptr, const Manager& manager) {
new (self) Dependency<Ptr, Manager>*(new Dependency<Ptr, Manager>(manager));
new (self_ptr) Ptr(dep_ptr(self)->get());
}
template <typename DependentManager = Manager,
std::enable_if_t<!std::is_lvalue_reference<DependentManager>::value,
int> = 0>
static void Construct(Storage self, Ptr* self_ptr, Manager&& manager) {
new (self) Dependency<Ptr, Manager>*(
new Dependency<Ptr, Manager>(std::forward<Manager>(manager)));
new Dependency<Ptr, Manager>(std::move(manager)));
new (self_ptr) Ptr(dep_ptr(self)->get());
}
template <
Expand Down Expand Up @@ -938,15 +944,18 @@ struct MethodsFor<Ptr, inline_size, inline_align, Manager,
Manager>::value>> {
static const Methods<Ptr> methods;

template <
typename DependentManager = Manager,
std::enable_if_t<!std::is_reference<DependentManager>::value, int> = 0>
template <typename DependentManager = Manager,
std::enable_if_t<!std::is_rvalue_reference<DependentManager>::value,
int> = 0>
static void Construct(Storage self, Ptr* self_ptr, const Manager& manager) {
new (self) Dependency<Ptr, Manager>(manager);
new (self_ptr) Ptr(dep(self).get());
}
template <typename DependentManager = Manager,
std::enable_if_t<!std::is_lvalue_reference<DependentManager>::value,
int> = 0>
static void Construct(Storage self, Ptr* self_ptr, Manager&& manager) {
new (self) Dependency<Ptr, Manager>(std::forward<Manager>(manager));
new (self) Dependency<Ptr, Manager>(std::move(manager));
new (self_ptr) Ptr(dep(self).get());
}
template <
Expand Down Expand Up @@ -1184,7 +1193,7 @@ template <typename Ptr, size_t inline_size, size_t inline_align>
template <typename Manager,
std::enable_if_t<
absl::conjunction<
absl::negation<std::is_reference<Manager>>,
absl::negation<std::is_rvalue_reference<Manager>>,
absl::negation<any_dependency_internal::IsAnyDependency<
Ptr, Manager>>>::value,
int>>
Expand All @@ -1195,15 +1204,20 @@ inline void AnyDependencyImpl<Ptr, inline_size, inline_align>::Initialize(
}

template <typename Ptr, size_t inline_size, size_t inline_align>
template <
typename Manager,
std::enable_if_t<
!any_dependency_internal::IsAnyDependency<Ptr, Manager>::value, int>>
template <typename Manager,
std::enable_if_t<
absl::conjunction<
absl::negation<std::is_lvalue_reference<Manager>>,
absl::negation<any_dependency_internal::IsAnyDependency<
Ptr, Manager>>>::value,
int>>
inline void AnyDependencyImpl<Ptr, inline_size, inline_align>::Initialize(
Manager&& manager) {
methods_ = &MethodsFor<Manager>::methods;
MethodsFor<Manager>::Construct(repr_.storage, &ptr_,
std::forward<Manager>(manager));
// `std::move(manager)` is correct and `std::forward<Manager>(manager)` is not
// necessary: `Manager` is never an lvalue reference because this is excluded
// in the constraint.
MethodsFor<Manager>::Construct(repr_.storage, &ptr_, std::move(manager));
}

template <typename Ptr, size_t inline_size, size_t inline_align>
Expand Down

0 comments on commit 2058690

Please sign in to comment.