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

Return type of sorter adapters #134

Open
Morwenn opened this issue Aug 15, 2018 · 2 comments
Open

Return type of sorter adapters #134

Morwenn opened this issue Aug 15, 2018 · 2 comments
Labels

Comments

@Morwenn
Copy link
Owner

Morwenn commented Aug 15, 2018

At first, sorter adapters were mostly designed to return the value returned by the wrapped sorters. However, with time some problems appeared with that design:

  1. Some adapters such as counting_adapter return a result. Currently it simply discards any value returned by the wrapped sorter and there is no way to get both values. This might become even more of a problem when using sorter adapters on measures of presortedness, or with sorting algorithms returning the end iterator as in the Ranges TS.
  2. Handling both sorters that return void and sorters that return a value is quite tricky when the adapter needs to perform operations after the return: returning the result of a void function is ok, but because of the lack of regular void in the language it's impossible to generically store the result to return it later. The easiest solution is still to execute the code that comes after the call to the sorter in a lambda passed to a scope_exit thingy (also hard to do prior to C++17 and std::uncaught_exceptions).
  3. Some adapters are not suited to actually return a useful result: for example verge_adapter is only useful to make algorithms take advantage of big runs in the collection. However adapting a measure of presortedness with it wouldn't make sense and there is no obvious way to produce the result once adapted, so verge_adapter is an example of an adapter that shouldn't forward the result of the underlying algorithm.

Now the first point is the most problematic one and the one for which there is no obvious solution. The possible solutions are as follows:

  • Keeping the status quo: adapters either return a value they computed or the value of the wrapped sorter if they don't return a value of their own.
  • Wrapping the values in a std::pair where one of the values is the one returned from the sorter and the other one is the one computed by the adapter. It becomes a usability problem if the nesting of adapters is too deep and I'd like a more scalable solution.
  • Wrapping the values in a std::tuple that is flattened through the adapter levels sounds like retrieving the exact result is hard.
  • I would rather see a solution with tagged tuples which feels slightly more scalable: instead of simply returning an end iterator, a sorter could return tagged_tuple<tag::out(Iterator)> and flattening the tagged_tuple through adapters could be a bit safer. To keep the usability we would probably need some kind of tagged single-value container which implicitly converts to the wrapped type. Apparently LEWG is willing to drop the whole tag mechanism, so this solution would require to reinvent the whole mechanism, which I'm not really willing to do...

To be honest I'm still not convinced by any of the solutions, hence this issue. Any somewhat sane idea to make that both usable and scalable is welcome.


A first use case that should always be considered to decide whether it makes for an adapter to return the result of the underlying sorter is: can it be used on a measure of presortedness? If it can it probably makes sense to forward the result of the adapted sorter, otherwise I don't know.

@Morwenn
Copy link
Owner Author

Morwenn commented Dec 4, 2018

Work done as of release 1.3.0:

  • schwartz_adapter returns the result of the adapted sorter in C++14 mode.
  • indirect_adapter returns the result of the adapted sorter in C++17 mode.
  • out_of_place_adapter returns the result of the adapted sorter in C++17 mode.

The adapters that only work in C++17 mode actually rely on the feature test macro __cpp_lib_uncaught_exceptions to be activated.

@Morwenn
Copy link
Owner Author

Morwenn commented Sep 5, 2019

As per #148, verge_adapter will be merged back into verge_sorter while still taking a fallback sorter as a parameter in cpp-sort 2.0.0, so we won't have to make it return anything since it won't be considered a generic adapter anymore.

@Morwenn Morwenn mentioned this issue Dec 11, 2022
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant