Guest

Untitled

By: a guest on Apr 9th, 2011  |  syntax: C++  |  size: 2.72 KB  |  hits: 217  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. /*
  2.  * Some examples of contrived MPL usage.
  3.  *
  4.  *
  5.  * James Brotchie 2011 - brotchie@gmail.com
  6.  */
  7.  
  8. #include <iostream>
  9.  
  10. #include <boost/mpl/vector.hpp>
  11. #include <boost/mpl/deref.hpp>
  12. #include <boost/mpl/count.hpp>
  13. #include <boost/mpl/unique.hpp>
  14. #include <boost/type_traits/is_same.hpp>
  15. #include <boost/mpl/at.hpp>
  16. #include <boost/mpl/map.hpp>
  17. #include <boost/mpl/has_key.hpp>
  18. #include <boost/mpl/pair.hpp>
  19. #include <boost/mpl/assert.hpp>
  20.  
  21. using namespace boost::mpl;
  22. using boost::is_same;
  23.  
  24. class basebase {
  25. public:
  26.     basebase(std::string name) : _name(name) {};
  27.     std::string getName() const {
  28.         return _name;
  29.     }
  30. protected:
  31.     std::string _name;
  32. };
  33.  
  34. class stringbase : public basebase {
  35. public:
  36.     stringbase() : basebase("String Base") {};
  37. };
  38.  
  39. class intbase : public basebase {
  40. public:
  41.     intbase() : basebase("Int Base") {};
  42. };
  43.  
  44. /* Map that allows us to choose the most appropriate
  45.    base class for a given type. */
  46. typedef map< pair<int, intbase>,
  47.              pair<long, intbase>,
  48.              pair<std::string, stringbase>> basemap;
  49.  
  50. template <typename T>
  51. struct printer : public at<basemap, T>::type {
  52.     /* Ensure that T is actually in basemap. */
  53.     BOOST_MPL_ASSERT((has_key<basemap, T>));
  54. };
  55.  
  56. int main() {
  57.     /* mpl::vector containing 6 types with duplicate long. */
  58.     typedef vector<short, std::string, long, long, double> types;
  59.  
  60.     /* Use types as an iterator, deref the first element.
  61.        i1 is of type sort. */
  62.     deref<begin<types>::type>::type i1 = 5;
  63.     /* Access the second element of types by incrementing using
  64.        next, then dereferencing.
  65.        s1 is of type std::string. */
  66.     deref<next<begin<types>::type>::type>::type s1 = "Hello World";
  67.  
  68.     /* Do the same as above but directly access elemnts 0 and 1 of
  69.        the mpl::vector. */
  70.     at_c<types, 0>::type i2 = 5;
  71.     at_c<types, 1>::type s2 = "Hello World";
  72.  
  73.     typedef pair<int, long> test;
  74.     first<test>::type i3 = 15;
  75.     second<test>::type i4 = 15;
  76.  
  77.     /* Get rid of duplicates from types vector. */
  78.     typedef unique<types, is_same<_1, _2>>::type unique_types;
  79.     /* Count how many longs are in the original types vector,
  80.        then count how many are in the 'uniqued' vector. */
  81.     std::cout << count<types, long>::value << std::endl;
  82.     std::cout << count<unique_types, long>::value << std::endl;
  83.  
  84.     /* Construct printer instances for int and std::string. */
  85.     printer<int> pi;
  86.     printer<std::string> ps;
  87.  
  88.     /* De-commenting this will cause a compile time assert,
  89.        because there's no 'double' key in basemap. */
  90.     //printer<double> pd;
  91.  
  92.     std::cout << pi.getName() << std::endl;
  93.     std::cout << ps.getName() << std::endl;
  94.  
  95.     return 0;
  96. }