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

Apply [[no_unique_address]] to predicates #1276

Merged
merged 2 commits into from
Aug 23, 2019

Conversation

morinmorin
Copy link
Contributor

@morinmorin morinmorin commented Aug 23, 2019

This PR applies RANGES_NO_UNIQUE_ADDRESS to functions/predicates in

  • transform, take_while, drop_while views
  • logical_negate

The latter allows to EBO out empty predicates in filter_view.

@ericniebler
Copy link
Owner

Does any compiler yet do anything meaningful with this attribute? I'm just curious.

@ericniebler ericniebler merged commit 65dde6d into ericniebler:master Aug 23, 2019
@morinmorin morinmorin deleted the view/space_saver branch August 23, 2019 18:07
@morinmorin
Copy link
Contributor Author

GCC 9 has [[no_unique_address]]. Clang trunk also has the attribute, though I didn't test on that compiler.

Here are the results of differences in size of views (before and after applying this patch, tested on GCC 9.2):

views before after
arr | transform 24 16
arr | transform | transform 40 24
arr | transform | transform | transform 56 32
transform(rng1, rng2, f) 24 24
arr | take_while 24 16
arr | drop_while 40 32
arr | filter 40 32
arr | remove_if 32 32

Source code:

#include <iostream>
#include <range/v3/core.hpp>
#include <range/v3/view.hpp>

struct F
{
    bool operator()(int x) const { return x % 2 == 0; }
    int operator()(int x, int y) const { return x + y; }
};

int main()
{
    using namespace ranges::views;

    int arr[3] = {4, 5, 6};
    
    std::cout << "arr | transform" << "\n";
    std::cout << sizeof(arr | transform(F{})) << "\n";

    std::cout << "arr | transform | transform" << "\n";
    std::cout << sizeof(arr | transform(F{}) | transform(F{})) << "\n";

    std::cout << "arr | transform | transform" << "\n";
    std::cout << sizeof(arr | transform(F{}) | transform(F{}) | transform(F{})) << "\n";

    std::cout << "transform (binary)" << "\n";
    std::cout << sizeof(transform(arr, arr, F{})) << "\n";

    std::cout << "arr | take_while" << "\n";
    std::cout << sizeof(arr | take_while(F{})) << "\n";

    std::cout << "arr | drop_while" << "\n";
    std::cout << sizeof(arr | drop_while(F{})) << "\n";

    std::cout << "arr | filter" << "\n";
    std::cout << sizeof(arr | filter(F{})) << "\n";

    std::cout << "arr | remove_if" << "\n";
    std::cout << sizeof(arr | remove_if(F{})) << "\n";
}

@ericniebler
Copy link
Owner

So cool! Thanks!

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

Successfully merging this pull request may close these issues.

None yet

2 participants