@@ -667,6 +667,9 @@ namespace STDEXEC::__any
667667 : _Interface<__mcall1<__bases_of<_Interface>, __value_proxy_root<_Interface>>>
668668 {};
669669
670+ template <class _Interface , __root_kind _RootKind>
671+ concept __has_root_kind = std::remove_reference_t <_Interface>::__root_kind == _RootKind;
672+
670673 // ////////////////////////////////////////////////////////////////////////////////////////
671674 // ! __interface_base
672675 template <template <class > class _Interface ,
@@ -693,15 +696,20 @@ namespace STDEXEC::__any
693696 ? _BufferAlignment
694697 : _Base::__buffer_alignment;
695698
699+ static constexpr bool __can_slice = __extension_of<_Base, __imovable>
700+ && (__has_root_kind<_Base, __root_kind::__value>
701+ || __extension_of<_Base, __icopyable>);
702+
696703 static constexpr bool __nothrow_slice =
697704 STDEXEC::__any::__nothrow_slice<__this_interface_type, _Base, __buffer_size>;
698705
699706 // ! @pre !empty(*this)
700- constexpr virtual void
701- __slice_to_ (__value_proxy_root<_Interface> &__result) noexcept (__nothrow_slice)
707+ constexpr virtual void __slice_to_ (__value_proxy_root<_Interface> &__result) //
708+ noexcept (__nothrow_slice)
702709 {
703710 STDEXEC_ASSERT (!__empty (*this ));
704- if constexpr (_Base::__box_kind != __box_kind::__abstract)
711+ STDEXEC_ASSERT (__can_slice);
712+ if constexpr (_Base::__box_kind != __box_kind::__abstract && __can_slice)
705713 {
706714 using __root_interface_t = _Base::__interface_type;
707715 constexpr bool __is_root_interface =
@@ -714,12 +722,15 @@ namespace STDEXEC::__any
714722 __value (*this ).__slice_to_ (__result);
715723 __reset (*this );
716724 }
717- else // if constexpr (_Base::__box_kind == __box_kind::__object )
725+ else if constexpr (_Base::__root_kind == __root_kind::__value )
718726 {
719727 // Move from type-erased values, but not from type-erased references
720- constexpr bool __is_value = (_Base::__root_kind == __root_kind::__value);
721728 // potentially throwing:
722- __result.emplace (STDEXEC_DECAY_COPY (STDEXEC::__move_if<__is_value>(__value (*this ))));
729+ __result.emplace (std::move (__value (*this )));
730+ }
731+ else
732+ {
733+ __result.emplace (__value (*this ));
723734 }
724735 }
725736 }
0 commit comments