fill_em_up.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*=============================================================================
  2. Copyright (c) 2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. Problem:
  6. So... you have an input sequence I and a target vector R. You want to
  7. copy I into R. But, I may have less elements than the result vector R.
  8. For those elements not in R, you want them to be default constructed.
  9. Here's a case:
  10. I: list<double, std::string>
  11. R: vector<double, std::string, int, short>
  12. You want the elements at the right of I not in R (i.e. int, short)
  13. default constructed. Those at the left, found in both I and R, you want
  14. to simply copy from I.
  15. Of course you want to be able to handle any type of I and R.
  16. ==============================================================================*/
  17. // We'll use these containers as examples
  18. #include <boost/fusion/container/list.hpp>
  19. #include <boost/fusion/container/vector.hpp>
  20. // For doing I/O
  21. #include <boost/fusion/sequence/io.hpp>
  22. // We'll use join and advance for processing
  23. #include <boost/fusion/algorithm/transformation/join.hpp>
  24. #include <boost/fusion/iterator/advance.hpp>
  25. // The fusion <--> MPL link header
  26. #include <boost/fusion/mpl.hpp>
  27. // Same-o same-o
  28. #include <iostream>
  29. #include <string>
  30. int
  31. main()
  32. {
  33. using namespace boost::fusion;
  34. using namespace boost;
  35. // Let's specify our own tuple delimeters for nicer printing
  36. std::cout << tuple_open('[');
  37. std::cout << tuple_close(']');
  38. std::cout << tuple_delimiter(", ");
  39. // Here's your input sequence
  40. typedef list<double, std::string> I;
  41. I i(123.456, "Hello");
  42. // Here's your output sequence. For now, it is just a typedef
  43. typedef vector<double, std::string, int, short> R;
  44. // Let's get the sizes of the sequences. Yeah, you already know that.
  45. // But with templates, you are simply given, say, R and I, corresponding
  46. // to the types of the sequences. You'll have to deal with it generically.
  47. static int const r_size = result_of::size<R>::value;
  48. static int const i_size = result_of::size<I>::value;
  49. // Make sure that I has no more elements than R
  50. // Be nice and catch obvious errors earlier rather than later.
  51. // Without this assert, the mistake will still be caught by Fusion,
  52. // but the error will point to somewhere really obscure.
  53. BOOST_STATIC_ASSERT(i_size <= r_size);
  54. // Let's get the begin and end iterator types of the output sequence
  55. // There's no actual vector yet. We just want to know the types.
  56. typedef result_of::begin<R>::type r_begin;
  57. typedef result_of::end<R>::type r_end;
  58. // Let's skip i_size elements from r_begin. Again, we just want to know the type.
  59. typedef result_of::advance_c<r_begin, i_size>::type r_advance;
  60. // Now, make MPL iterators from r_advance and r_end. Ditto, just types.
  61. typedef mpl::fusion_iterator<r_advance> mpl_r_advance;
  62. typedef mpl::fusion_iterator<r_end> mpl_r_end;
  63. // Make an mpl::iterator_range from the MPL iterators we just created
  64. // You guessed it! --just a type.
  65. typedef mpl::iterator_range<mpl_r_advance, mpl_r_end> tail;
  66. // Use join to join the input sequence and our mpl::iterator_range
  67. // Our mpl::iterator_range is 'tail'. Here, we'll actually instantiate
  68. // 'tail'. Notice that this is a flyweight object, typically just 1 byte
  69. // in size -- it doesn't really hold any data, but is a fully conforming
  70. // sequence nonetheless. When asked to return its elements, 'tail' returns
  71. // each element default constructed. Breeds like a rabbit!
  72. // Construct R from the joined sequences:
  73. R r(join(i, tail()));
  74. // Then finally, print the result:
  75. std::cout << r << std::endl;
  76. return 0;
  77. }