3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-27 06:43:40 +01:00
dft_tools/doc/reference/c++/arrays/foreach.rst
Olivier Parcollet 3fe400d34c doc : split c++ code from rst
- examples split from the rst file using a python script (split_code).
- Final result for the doc is unchanged.
- examples are compiled and tested with the other tests.
- examples' code have been clang-formatted, with triqs style.
- doc compiles much faster, and with the same options as the rest of the
  test.
- examples are added as tests, so they are run by make test, as simple C
  tests.
- done for the tutorials and the reference.
- autocompile removed (changed into triqs_example directive).
- add triqs_example :
   - make a literal include of the source code.
   - runs the compiled example
   - add, as before, the result to the source code in the doc.
- added the script split_code, used to make the changes automatically,
  maybe for later reuse. (in _tools)
2014-05-31 23:00:16 +02:00

88 lines
2.8 KiB
ReStructuredText

.. highlight:: c
.. _Foreach:
Loops : the foreach constructs
========================================================
foreach and its variants are a compact and efficient way to
perform some action of the kind
*For all indices of the array, do something*
While this kind of construct is equivalent to write manually the *for* loops, it has
several advantages :
* it is more compact, less error prone (one does not need to specify the bounds in the loop).
* the library orders the for loop in the most efficient way to traverse the memory.
Hence if one change the TraversalOrder for some arrays, there is no need to change the for loop
ordering to obtain a better performance, just recompile...
* it is easier to write generic code for array of several dimensions.
foreach
------------
The *foreach* function call a given function *f* successively on the indices of an array *A*,
in the order specified by the TraversalOrder flag of the array.
* Synopsis::
template <typename ArrayType, typename Function>
void foreach (ArrayType const & A, Function F);
* A is an array/matrix/vector or the corresponding view.
* The template is enabled iif ImmutableArray<ArrayType>::value == true
* F is a function with the following synopsis ::
F(size_t ... indices)
* The foreach algorithm is equivalent to ::
for (i,j,k...) F(i,j,k...)
* The for loop are automatically organised to optimize the traversal order of A
using the TraversalOrder flag of the array.
* As a result this is always equally or more optimized than a manually written loop.
Example :
.. triqs_example:: ./foreach_0.cpp
.. note::
You *can* pass a std::function as Function, but it is not recommended in critical parts of the code.
The indirection caused by std::function at each call may lead to big performance penalty.
The call to lambda, or a custom callable object will on the other hand by inlined.
assign_foreach
----------------
assign_foreach is a simpler form that assigns the return value of the function to the array elements.
Note that using the lazy expression is usually a lot simpler (except when you already have the function ready).
Synopsis::
template <typename ArrayType, typename Function>
void assign_foreach (ArrayType const & A, Function F);
* A is an array/matrix/vector or the corresponding view.
* The template is enabled iif ImmutableArray<ArrayType>::value == true
* F is a function with the following synopsis ::
F(size_t ... indices)
* The assign_foreach algorithm is equivalent to ::
for (i,j,k...) A(i,j,k...) = F(i,j,k...)
* The for loop are automatically organised to optimize the traversal order of A
using the TraversalOrder flag of the array.
.. triqs_example:: ./foreach_1.cpp
.. note::
Cf the note of the *foreach* function.