Boost.Foreach

Boost.Foreach is a library that makes the syntax of iterating over elements in a sequence simpler and more readable. Even though it offers no functionality over and above a simple for loop it significantly reduces the need for repetitive code and improves the clarity of the remaining code. The simplest example of usage is:

/// Define a vector of 10 elements all with value 1.0
std::vector<double> v(10,1.0);
/// Add 3.0 to each element
BOOST_FOREACH(double &x, v)
{
  x+= 3.0;
}

The key features of the library are:

  • Easy iteration over most types of sequences, including all STL containers, strings, and objects that define begin() and end() methods
  • The variable to which the elements of the sequence are bound can be a reference, allowing modification of the elements
  • Negligible overheads due to careful design:
    • No virtual calls
    • No function pointers
    • No unnecessary copies of variables

The usage of this library is recommended where normally you would have created a for loop with an iterator that then proceeds through a sequence and processes the elements. More precisely, where you would have used code of the form:

for(std::vector<myT>::iterator i= m.begin();
    i != m.end();
    ++i)
{
    // operate on i
}

You can use:

BOOST_FOREACH(myT  &i, m)
{
  // operate on i
}

Small overheads mean BOOST_FOREACH may be used throughout an application and only might need to be avoided in the sections which are identified as the most performance critical.

Here is a complete example, illustrating a potential simple application in QF, namely generating a sequence of values iid from the chi-squared distribution with one degree of freedom:

#include <vector>
#include <cmath>

#include <boost/random/normal_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/foreach.hpp>


int main(void)
{
  // Define a generator of Gaussian random numbers
  boost::variate_generator<boost::mt19937, boost::normal_distribution<> >
    generator(boost::mt19937(43),
              boost::normal_distribution<>());

  // Define a vector of 10 elements
  std::vector<double> v(10);

  // Assign each element iid from chi-squared distribution with 1 dof
  BOOST_FOREACH(double &x, v)
  {
    x=std::pow(generator(),2);
  }

  // Print each element
  BOOST_FOREACH(double x, v)
  {
    std::cout<<x<<", ";
  }
}