6.6. Sequence Building AlgorithmsAll of MPL's sequence building algorithms follow the same pattern. It's a little bit elaborate, but as a result the algorithms are extremely easy to use. The pattern is as follows, for any sequence building algorithm xxxx.
Let's see how this plays out in practice. In the following examples, v123 indicates a type with "vector properties" equivalent to mpl::vector_c<int, 1,2,3>. Similarly, 1876 indicates a type equivalent to mpl::list_c<int, 8,7,6>. // starting sequences typedef mpl::vector_c<int, 1, 2, 3> v123; typedef mpl::list_c<int, 1, 2, 3> l123; // transformation typedef mpl::plus<_1,mpl::int_<5> > add5; // using the default inserters typedef mpl::transform<v123, add5>::type v678; typedef mpl::transform<l123, add5>::type l678; typedef mpl::reverse_transform<v123, add5>::type v876; typedef mpl::reverse_transform<l123, add5>::type l876; Thus, the simple no-inserter forms produce the expected result for both front-extensible and back-extensible sequences. In order to use the versions with inserters, though, we have to be aware of both the algorithm's traversal direction and the properties of the sequence we're building: // this inserter is equivalent to the default typedef mpl::transform< v123, add5, mpl::back_inserter<mpl::vector<> > >::type v678; // also equivalent to the default typedef mpl::reverse_transform< l123, add5, mpl::front_inserter<mpl::list<> > >::type l678; // properties of input sequence don't affect the result typedef mpl::reverse_transform< v123, add5, mpl::front_inserter<mpl::list<> > >::type l678; The inserter used in building a new sequence should always be determined by the front- or back-extensibility of the result sequence. The library's default inserter selection follows the same rule; it just happens that the properties of the result sequence when there is no user-supplied inserter are the same as those of the input sequence. Table 6.2 summarizes the sequence building algorithms. Note that neither the reverse_ forms nor those with the optional inserter arguments are listed, but it should be possible to deduce their existence and behavior from the description above. They are also covered in detail in the MPL reference manual. We should note that copy and reverse are exceptions to the naming rule: They are reversed versions of one another, and there is neither a reverse_copy nor a reverse_reverse algorithm in the library.
The sequence building algorithms all have linear complexity, and all return a sequence of the same type as their first input sequence by default, but using an appropriate inserter you can produce any kind of result you like.
Because we've left the reverse_ algorithms out of Table 6.2 it's only fair that we point out that the form of unique that accepts an equivalence relation is, well, unique among all of the sequence building algorithms. The reverse_ forms of most algorithms produce the same elements as the normal forms do (in reverse order), but the elements of sequences produced by unique and reverse_unique for the same arguments may differ. For example: typedef mpl::equal_to< mpl::shift_right<_1, mpl::int_<1> > , mpl::shift_right<_2, mpl::int_<1> > > same_except_last_bit; // predicate typedef mpl::vector_c<int, 0,1,2,3,4,5> v; typedef unique< v, same_except_last_bit >::type v024; // 0, 2, 4 typedef reverse_unique< v, same_except_last_bit >::type v531; // 5, 3, 1 |