Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[xutility] Modernize _Ptr_meow_cat to use variable templates #872

Closed
wants to merge 3 commits into from

Conversation

miscco
Copy link
Contributor

@miscco miscco commented May 30, 2020

This is a work in progress for #860 that I started yesterday.

With @StephanTLavavej awesome work on _Equal_memcmp_is_safe it went quite well.

  • I use an enum to differentiate between the different categories. Is that ok or should I use some other means of discriminating between the categories.

  • There is some unfortunate code duplication because enable_if does not work on specializations of variable templates. (It complains about an unused template argument). Is that ok or has somebody a better idea?

  • Names are hard

  • That said there is some bug I need to hunt but I wanted to get the overal feedback on the approach.

  • The unwrap_enum_t part is terrible I will most likelybuild a helper template for that

@miscco miscco requested a review from a team as a code owner May 30, 2020 07:47
@miscco miscco force-pushed the memcpy_able branch 4 times, most recently from 8ae08c2 to 4643f4f Compare May 30, 2020 17:57
@miscco
Copy link
Contributor Author

miscco commented May 30, 2020

@CaseyCarter This passes without ranges support. The problem is again that contiguous_iterator<volatile int*> returns false, which breaks all the tests in C++20 mode.

I seem to remember that you already filed an issue regarding some bug in the ternary operator that leads to common_with to be false but was unable to find it. Has that been resolved?

@miscco
Copy link
Contributor Author

miscco commented May 30, 2020

I also found that iter_value_t breaks everything here. I would have thought I could use it instead of remove_cv_t<remove_reference_t<_Iter_ref_t<_Iter1>>> but ...

e.g. std::iter_value_t<std::ostreambuf_iterator<char,std::char_traits<char>>> gives me this error

error C2794: 'value_type': is not a member of any direct or indirect base class of 'std::indirectly_readable_traits<std::ostreambuf_iterator<char,std::char_traits>>'
indirectly_readable_traits<remove_cvref_t<_Ty>>, iterator_traits<remove_cvref_t<_Ty>>>::value_type;

@miscco
Copy link
Contributor Author

miscco commented May 31, 2020

I have trouble understanding the test errors, as those specializations they complain do work fine in the test.

Can somebody that understands meta programming help?

@miscco
Copy link
Contributor Author

miscco commented Jun 1, 2020

So it seems that the two overloads for same type copy and pointer copy were indeed ambiguous if _Source == _Dest.

I added some SFINAE or that to same type copy specializations.

There is still a question why MSVC accepts this code when then other major compilers do.

I will try to condense this down a bit and create a ticket

EDIT: filed here https://developercommunity.visualstudio.com/content/problem/1058776/compiler-accepts-ambiguous-overload-of-variable-te.html

stl/inc/xutility Outdated Show resolved Hide resolved
@CaseyCarter CaseyCarter added the throughput Must compile faster label Jun 3, 2020
@miscco
Copy link
Contributor Author

miscco commented Jun 3, 2020

@CaseyCarter can I get some direction on how to fix the ostreambuf mess?

stl/inc/xutility Outdated Show resolved Hide resolved
stl/inc/memory Outdated Show resolved Hide resolved
stl/inc/xmemory Outdated Show resolved Hide resolved
stl/inc/xmemory Outdated Show resolved Hide resolved
stl/inc/xutility Outdated Show resolved Hide resolved
stl/inc/xutility Outdated Show resolved Hide resolved
stl/inc/xutility Outdated Show resolved Hide resolved
stl/inc/xutility Outdated Show resolved Hide resolved
tests/std/tests/VSO_0180469_ptr_cat/test.cpp Outdated Show resolved Hide resolved
stl/inc/xutility Outdated Show resolved Hide resolved
@miscco
Copy link
Contributor Author

miscco commented Jun 8, 2020

I addressed most of the stylistic comments and will have a look on how to fix those failures

@miscco
Copy link
Contributor Author

miscco commented Jun 8, 2020

This is driving me crazy. Why it is trying to do sizeof(void) in _Can_memcpy_integrals when is_integral<void> should already have returned false?

@AdamBucior
Copy link
Contributor

This is driving me crazy. Why it is trying to do sizeof(void) in _Can_memcpy_integrals when is_integral<void> should already have returned false?

std::conjunction short circuiting doesn't work that way. Template parameters need to be evaluated before template is instantiated. You need:

template <class _Source, class _Dest>
struct _Find_some_name_for_this_struct
{
    static constexpr bool value = sizeof(_Source) == sizeof(_Dest) && is_same_v<bool, _Source> == is_same_v<bool, _Dest>;
};

and then:

constexpr bool _Can_memcpy_integrals = conjunction_v<is_integral<_Source>, is_integral<_Dest>,
    _Find_some_name_for_this_struct<_Source, _Dest>>;

@miscco
Copy link
Contributor Author

miscco commented Jun 8, 2020

This is driving me crazy. Why it is trying to do sizeof(void) in _Can_memcpy_integrals when is_integral<void> should already have returned false?

std::conjunction short circuiting doesn't work that way. Template parameters need to be evaluated before template is instantiated. You need:

template <class _Source, class _Dest>
struct _Find_some_name_for_this_struct
{
    static constexpr bool value = sizeof(_Source) == sizeof(_Dest) && is_same_v<bool, _Source> == is_same_v<bool, _Dest>;
};

and then:

constexpr bool _Can_memcpy_integrals = conjunction_v<is_integral<_Source>, is_integral<_Dest>,
    _Find_some_name_for_this_struct<_Source, _Dest>>;

Argh damn it, I am always forgetting that...

@miscco
Copy link
Contributor Author

miscco commented Jun 9, 2020

I am super unhappy that I had to essentially roll back the most useful changes to go back to that pointer only specialization.

However, it seems like there are some deficiencies wrt iter_reference_t and iter_value_t

@miscco
Copy link
Contributor Author

miscco commented Jun 10, 2020

I think this should be ready for the next round of reviews

stl/inc/xutility Outdated Show resolved Hide resolved
stl/inc/xmemory Outdated
Comment on lines 1694 to 1725
bool_constant < _Can_memmove_uninitialized<decltype(_UFirst),
_Ptrval> && _Uses_default_construct<_Alloc, _Ptrval, decltype(_STD move(*_UFirst))>::value > {}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the spacing around bool_constant is different here than in other occurrences (specifically before and after the < and >), and it also looks like it is preexisting in the code before changes. Is there a reason for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is clang format getting confused by the _Uses_default_construct<_Alloc, _Ptrval, decltype(_STD move(*_UFirst))>::value > {} afterwards

I was not able to create a simple reproducer though

bool_constant<_Can_memop_elements<remove_cv_t<_Source>, remove_volatile_t<_Dest>, _Cat>>>;

template <class _IterSource, class _IterDest, _Memop_cat _Cat>
_INLINE_VAR constexpr bool _Can_memop<move_iterator<_IterSource>, _IterDest, _Cat> =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't _Copy and _Copy_uninitialized become _Move and _Move_uninitialized with move_iterator? (I know it's pre-existing but it's definitely wrong)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you are right that for the _Copy case it seems wrong. For _Copy_uninitialized we require trivial types anyway where it does not make a difference.

Thatsaid I am absolutely in favor of changing it accordingly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we fixed it in #1772 it's no longer pre-existing so we should change this accordingly.

Copy link
Member

@StephanTLavavej StephanTLavavej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has merge conflicts now that we're using if constexpr unconditionally.

Base automatically changed from master to main January 28, 2021 00:35
@CaseyCarter CaseyCarter self-assigned this Mar 3, 2021
@miscco
Copy link
Contributor Author

miscco commented Mar 23, 2021

@CaseyCarter I have rebased and updated the PR. I think we should decide whether this is worth it or simply put it in the bin

stl/inc/memory Outdated
Comment on lines 81 to 82
if constexpr (is_same_v<_Se,
_It> && is_same_v<_OSe, _Out> && _Memmove_in_uninitialized_copy_is_safe<_It, _Out>) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gods have failed me :(

Copy link
Member

@StephanTLavavej StephanTLavavej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a number of merge conflicts - can you resolve them?

@miscco
Copy link
Contributor Author

miscco commented Apr 30, 2021

Yeah, will do over the weekend

Copy link
Member

@StephanTLavavej StephanTLavavej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After merging your #1771, there's a conflict in <vector>.

@miscco
Copy link
Contributor Author

miscco commented Aug 6, 2021

So I am going to drop this and replace it with a sequence of smaller less error prone PRs:

  1. Add variable templates for the type aliases and use them in the Codebase
    2.-N Refactor the implementation of each variable template into a right thing.

Does that sound like a plan?

@miscco miscco closed this Aug 6, 2021
@AdamBucior
Copy link
Contributor

Yeah, I think it's a good idea to split this into smaller PRs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
throughput Must compile faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants