diff --git a/example/cookbook/fill_em_up.cpp b/example/cookbook/fill_em_up.cpp new file mode 100644 index 00000000..321068d7 --- /dev/null +++ b/example/cookbook/fill_em_up.cpp @@ -0,0 +1,99 @@ +/*============================================================================= + Copyright (c) 2006 Joel de Guzman + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) + + Problem: + + So... you have an input sequence I and a target vector R. You want to + copy I into R. But, I may have less elements than the result vector R. + For those elements not in R, you want them to be default conctructed. + Here's a case: + + I: list + R: vector + + You want the elements at the right of I not in R (i.e. int, short) + default constructed. Those at the left, found in both I and R, you want + to simply copy from I. + +==============================================================================*/ + +// We'll use these containers +#include +#include + +// For doing I/O +#include + +// We'll use join and advance +#include +#include + +// The fusion <--> MPL link header +#include + +// Same-o same-o +#include +#include + +int +main() +{ + using namespace boost::fusion; + using namespace boost; + + // Let's specify our own tuple delimeters for nicer printing + std::cout << tuple_open('['); + std::cout << tuple_close(']'); + std::cout << tuple_delimiter(", "); + + // Here's your input sequence + typedef list I; + I i(123.456, "Hello"); + + // Here's your output sequence. For now, it is just a typedef + typedef vector R; + + // Let's get the sizes of the sequences. Yeah, you already know that. + // But with templates, where you are simply given, say, R and I, + // corresponding to the types of the sequences, you'll have to deal + // with it generically. + static int const r_size = result_of::size::value; + static int const i_size = result_of::size::value; + + // Make sure that I has no more elements than R + BOOST_STATIC_ASSERT(i_size <= r_size); + + // Let's get the begin and end iterator types of the output sequence + // There's no actual vector yet. We just want to know the types. + typedef result_of::begin::type r_begin; + typedef result_of::end::type r_end; + + // Let's skip i_size elements from r_begin. Again, we just want to know the type. + typedef result_of::advance_c::type r_advance; + + // Now, make MPL iterators from r_advance and r_end. Ditto, just types. + typedef mpl::fusion_iterator mpl_r_advance; + typedef mpl::fusion_iterator mpl_r_end; + + // Make an mpl::iterator_range from the MPL iterators we just created + // You guessed it! --just a type. + typedef mpl::iterator_range tail; + + // Use join to join the input sequence and our mpl::iterator_range + // Our mpl::iterator_range is 'tail'. Here, we'll actually instantiate + // 'tail'. Notice that this is a flyweight object, typically just 1 byte + // in size -- it doesn't really hold any data, but it is a fully conforming + // sequence nonetheless. When asked to return its elements, 'tail' returns + // each element default constructed. Breeds like a rabbit! + R r(join(i, tail())); + + // Then finally, print the result: + std::cout << r << std::endl; + + return 0; +} +