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!