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

Provide C++20-style operator| to filter iterator ranges. #12952

Merged
merged 4 commits into from Nov 17, 2021

Conversation

bangerth
Copy link
Member

In the same spirit as provided by the C++20 range adaptors feature, this little function makes it possible to "filter" ranges over the active cells of Triangulation and DoFHandler objects.

This allows to replace:

  DoFHandler<dim> dof_handler;
  ...
  for (const auto &cell : dof_handler.active_cell_iterators())
    {
      if (cell->is_locally_owned())
        {
          fe_values.reinit (cell);
          ...do the local integration on 'cell'...;
        }
    }

by:

  DoFHandler<dim> dof_handler;
  ...
  const auto filtered_iterators_range =
    filter_iterators();
  for (const auto &cell :
          dof_handler.active_cell_iterators() | IteratorFilters::LocallyOwnedCell())
    {
      fe_values.reinit (cell);
      ...do the local integration on 'cell'...;
    }

Here, the operator| is to be interpreted in the same way as is done in the range adaptors feature that is part of C++20. It has
the same meaning as the | symbol on the command line: It takes what is on its left as its inputs, and filters and transforms to produce some output. In the example above, it "filters" all of the active cell iterators and removes those that do not satisfy the predicate -- that is, it produces a range of iterators that only contains those cells that are both active and locally owned.

I've wanted to do this for a long time because the syntax of range adaptors (of which filters are a special case) is so elegant. It turns out that if one looks at what we already have, it was all there: We just had it in a free function filter_iterators(), rather than an operator|().

The last commit here converts a few random places to see whether this all actually works :-)

/rebuild

Copy link
Member

@masterleinad masterleinad left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@masterleinad
Copy link
Member

You need to resolve some merge conflicts.

/rebuild

@bangerth
Copy link
Member Author

Rebased. Let's see whether this works.

@drwells drwells merged commit 1dd8bfa into dealii:master Nov 17, 2021
@bangerth bangerth deleted the filters branch November 17, 2021 18:29
@bangerth
Copy link
Member Author

Yay. I really like this syntax :-)

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

Successfully merging this pull request may close these issues.

None yet

3 participants