diff --git a/riegeli/base/any.h b/riegeli/base/any.h index 7ac81a48..b5ef4d3b 100644 --- a/riegeli/base/any.h +++ b/riegeli/base/any.h @@ -136,7 +136,7 @@ class // Initializes the state, avoiding a redundant indirection and adopting them // from `manager` instead if `Manager` is already a compatible `Any` or - // `AnyRef`. + // `AnyRef`, or an rvalue reference to it. void Initialize(); template ::value, int> = 0> @@ -617,24 +617,19 @@ template ::value, int>> inline void AnyBase::Initialize( Manager&& manager) { + using ManagerValue = std::remove_reference_t; // `manager.methods_and_handle_.methods->used_size <= - // Manager::kAvailableSize`, hence if - // `Manager::kAvailableSize <= - // AvailableSize()` then - // `manager.methods_and_handle_.methods->used_size <= - // AvailableSize()`. + // ManagerValue::kAvailableSize`, hence if + // `ManagerValue::kAvailableSize <= kAvailableSize` then + // `manager.methods_and_handle_.methods->used_size <= kAvailableSize`. // No need to check possibly at runtime. - if ((Manager::kAvailableSize <= - AvailableSize() || - manager.methods_and_handle_.methods->used_size <= - AvailableSize()) && + if ((ManagerValue::kAvailableSize <= kAvailableSize || + manager.methods_and_handle_.methods->used_size <= kAvailableSize) && // Same for alignment. - (Manager::kAvailableAlign <= - AvailableAlign() || - manager.methods_and_handle_.methods->used_align <= - AvailableAlign())) { + (ManagerValue::kAvailableAlign <= kAvailableAlign || + manager.methods_and_handle_.methods->used_align <= kAvailableAlign)) { // Adopt `manager` instead of wrapping it. - if (Manager::kAvailableSize == 0 || inline_size == 0) { + if (inline_size == 0 || ManagerValue::kAvailableSize == 0) { // Replace an indirect call to `methods_and_handle_.methods->move()` with // a plain assignment of `methods_and_handle_.handle` and a memory copy of // `repr_`. diff --git a/riegeli/base/any_initializer.h b/riegeli/base/any_initializer.h index b04a3a00..f8033a52 100644 --- a/riegeli/base/any_initializer.h +++ b/riegeli/base/any_initializer.h @@ -195,19 +195,21 @@ void AnyInitializer::ConstructMethod( TypeErasedRef context, MethodsAndHandle& methods_and_handle, Storage storage, size_t available_size, size_t available_align) { using Target = TargetT; + using TargetValue = std::remove_reference_t; // Materialize `Target` to consider adopting its storage. [&](Target&& target) { // `target.methods_and_handle_.methods->used_size <= - // Target::kAvailableSize`, hence if `Target::kAvailableSize == 0` then + // TargetValue::kAvailableSize`, hence if + // `TargetValue::kAvailableSize == 0` then // `target.methods_and_handle_.methods->used_size <= available_size`. // No need to check possibly at runtime. - if ((Target::kAvailableSize == 0 || + if ((TargetValue::kAvailableSize == 0 || target.methods_and_handle_.methods->used_size <= available_size) && // Same for alignment. - (Target::kAvailableAlign == 0 || + (TargetValue::kAvailableAlign == 0 || target.methods_and_handle_.methods->used_align <= available_align)) { // Adopt `target` instead of wrapping it. - if (Target::kAvailableSize == 0) { + if (TargetValue::kAvailableSize == 0) { // Replace an indirect call to `methods_and_handle_.methods->move()` // with a plain assignment of `methods_and_handle_.handle` and a memory // copy of `repr_`. @@ -238,7 +240,7 @@ void AnyInitializer::ConstructMethod( // necessary: `Target` is always an `Any`, never an lvalue reference. MethodsFor::Construct( storage, &methods_and_handle.handle, std::move(target)); - }(Initializer>(context.Cast()).Reference()); + }(Initializer(context.Cast()).Reference()); } } // namespace riegeli diff --git a/riegeli/base/any_internal.h b/riegeli/base/any_internal.h index fd778544..a041a25b 100644 --- a/riegeli/base/any_internal.h +++ b/riegeli/base/any_internal.h @@ -193,7 +193,8 @@ struct MethodsFor; template struct NullMethods; -// `IsAny` detects `Any` or `AnyRef` type with the given `Handle`. +// `IsAny` detects `Any` or `AnyRef` type with the given `Handle`, or an rvalue +// reference to it. template struct IsAny : std::false_type {}; @@ -201,9 +202,13 @@ struct IsAny : std::false_type {}; template struct IsAny> : std::true_type { }; + template struct IsAny> : std::true_type {}; +template +struct IsAny : IsAny {}; + // Implementation details follow. template