More C++ Idioms/Boost mutant
Boost mutant
[edit | edit source]Intent
[edit | edit source]Reorder 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
[edit | edit source]Motivation
[edit | edit source]The 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
[edit | edit source]Boost 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
[edit | edit source]Related Idioms
[edit | edit source]References
[edit | edit source]- ↑ Capeletto, Matias. "Boost.Bimap".
- ↑ http://beta.boost.org/doc/libs/1_43_0/libs/bimap/test/test_mutant.cpp