Creating Pair of Objects Using Boost Range and Lambda
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.
|
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); }); |
Leave a Reply
Want to join the discussion?Feel free to contribute!