Creating Pair of Objects Using Boost Range and Lambda

Tips and Tricks

In our programming environment, we use finite-volume method to solve differential equations. In this approach the domain is partitioned into “cell” and fluxes are evaluated at cell face (cell is made of 2 cell face or pair of cell face). Recently we have migrated our application to C++11/14 and start using new features of the compiler such as bind and lambda expression.   Below we present code snippets that use these 2 features to create pair of object.

const double wXmax = w_U1->grid().xMax(1);

We define some useful “typedef” to make code more readable and cleaner. Note that we use Boost range library utility (iterator range and range).

 using namespace std;

using namespace boost;

using namespace std::placeholders;

typedef std::list<cellFace>::iterator list_iter; // list iterator

typedef iterator_range<list_iter> iter_cellface; // iterator list range

typedef range_iterator<iter_cellface>::type range_iter; // range iterator type

typedef range_difference<iter_cellface>::type diff_type; // range difference

 Manipulating range

From global discretization concept we have the list of all faces for this discretization (mesh).  We declare 2 ranges (subrange): [begin, end-1] and the second range [begin+1, end], because we want to create pair of adjacent element.  We create 2 range with offset at both end  (subrange of the whole range which is the list of cellFace). We make use of the boost range iterator library.

 // [begin,end-1[

iter_cellface w_rngFace = make_iterator_range(m_listFaces).advance_end(-1);

// [begin+1,end[

iter_cellface w_rngFacep1 = make_iterator_range(m_listFaces).advance_begin(1);

Creating pair of cellFace

We can do it in 2 different ways, first using a “functor” or function object and then use the bind adaptor. Second we simply use a lambda expression.  In both case, the transform algorithm from std library is used.

 template <typename T, typename U>struct pair_creator : std::binary_function<T, U, std::pair<T, U>>

{

std::pair<T, U> operator() ( const T& arg1, const U& arg2 ) const{return std::make_pair( arg1, arg2 );

}

};

 

 // making pair by using bind adaptor

std::transform( w_rngFace.begin(), w_rngFace.end(), w_rngFacep1.begin(),

m_cellFacesPair.begin(), // store pair of faces

std::bind( pair_creator<cellFace, cellFace>(),_1,_2)); // binder

Using Lambda Expression from C++11

Create a pair of cell face by using the transform algorithm with lambda expression (use the 2 subrange defined above)

 transform( w_rngFace.begin(), w_rngFace.end(), w_rngFacep1.begin(), // range of faces

m_cellFacesPair.begin(), // store pair of faces

[]( const cellFace& aFace1, const cellFace& aFace2) // lambda expression

{

return std::make_pair(aFace1,aFace2);

});

 

clients and partners

Autolog