More C++ Idioms/Boost mutant
Boost mutant
edit
Intent
editReorder the data members of a plain old data (POD) type when all members are of the same type, without physically reorganizing or copying the data items.
Also Known As
editMotivation
editThe need of this idiom is best motivated using Boost's Bimap.[1] Boost.Bimap is a bidirectional maps library for C++. In bimap<X,Y>
, values of types X and Y can both serve as keys. The implementation of such a data structure can be optimized using the boost mutant idiom.
Solution and Sample Code
editBoost mutant idiom makes use of reinterpret_cast and depends heavily on the assumption that the memory layouts of two different structures with identical data members (types and order) are interchangeable. Although the C++ standard does not guarantee this property, virtually all the compilers satisfy it. Moreover, the mutant idiom is standard if only POD types are used.[2] The following example shows how the boost mutant idiom works.
template <class Pair>
struct Reverse
{
typedef typename Pair::first_type second_type;
typedef typename Pair::second_type first_type;
second_type second;
first_type first;
};
template <class Pair>
Reverse<Pair> & mutate(Pair & p)
{
return reinterpret_cast<Reverse<Pair> &>(p);
}
int main(void)
{
std::pair<double, int> p(1.34, 5);
std::cout << "p.first = " << p.first
<< ", p.second = " << p.second << std::endl
<< "mutate(p).first = " << mutate(p).first
<< ", mutate(p).second = " << mutate(p).second << std::endl;
}
Given a std::pair<X,Y>
object of POD data members only, the layout of the Reverse<std::pair<X,Y>>
is identical to that of pair's on most compilers. The Reverse
template reverses the names of the data members without physically reversing the data. A helper mutate
function is used to easily construct a Reverse<Pair>
reference, which can be considered as a view over the original pair object. The output of the above program confirms that the reverse view can be obtained without reorganizing data:
p.first = 1.34, p.second = 5 mutate(p).first = 5, mutate(p).second = 1.34
Known Uses
editRelated Idioms
editReferences
edit- ↑ Capeletto, Matias. "Boost.Bimap".
- ↑ http://beta.boost.org/doc/libs/1_43_0/libs/bimap/test/test_mutant.cpp