Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.19 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4.  
  5. enum Size {
  6.   small,
  7.   medium,
  8.   large
  9. };
  10.  
  11. enum Color {
  12.   red,
  13.   green,
  14.   blue
  15. };
  16.  
  17. struct Item {
  18.   std::string name;
  19.   Size size;
  20.   Color color;  
  21.   Item(const std::string& name, Size size, Color color):
  22.   name(name)
  23.   ,size(size)
  24.   ,color(color) {}
  25. };
  26.  
  27. struct ItemContainer {
  28.   std::vector<Item> items;
  29.  
  30.   void addItem(const Item& item) {
  31.     items.push_back(item);
  32.   }
  33.  
  34.   std::vector<Item>& getItems() {
  35.     return items;
  36.   }
  37. };
  38.  
  39. template <typename T>
  40. struct AndSpecification;
  41.  
  42. template <typename T>
  43. struct OrSpecification;
  44.  
  45. template <typename T>
  46. struct Specification {
  47.   virtual bool is_satisfied(const T&) const = 0;
  48.  
  49.   AndSpecification<T> operator&&(const Specification<T>& other) {
  50.     return AndSpecification<T>(*this, other);
  51.   }
  52.  
  53.   OrSpecification<T> operator||(const Specification<T>& other) {
  54.     return OrSpecification<T>(*this, other);
  55.   }
  56. };
  57.  
  58. template <typename T>
  59. struct Filter {
  60.   virtual std::vector<T*> filter(ItemContainer& container, const Specification<T>& spec) {
  61.     auto &vec = container.getItems();
  62.  
  63.     std::vector<T*> res;
  64.  
  65.      for (auto& i: vec) {
  66.        if (spec.is_satisfied(i)) {
  67.          res.push_back(&i);
  68.        }
  69.      }
  70.  
  71.      return res;
  72.   };
  73. };
  74.  
  75. struct SizeSpecification: Specification<Item> {
  76.   Size size;
  77.   SizeSpecification(Size size): size(size) {}
  78.  
  79.    bool is_satisfied(const Item& item) const {
  80.      return item.size == size;
  81.    }
  82. };
  83.  
  84. struct ColorSpecification: Specification<Item> {
  85.   Color color;
  86.   ColorSpecification(Color color): color(color) {}
  87.  
  88.   bool is_satisfied(const Item& item) const {
  89.     return item.color == color;
  90.   }
  91. };
  92.  
  93. template <typename T>
  94. struct OrSpecification: Specification<T> {
  95.   const Specification<T>& specLeft;
  96.   const Specification<T>& specRight;
  97.  
  98.   OrSpecification(const Specification<T>& specLeft, const Specification<T>& specRight):
  99.     specLeft(specLeft)
  100.     ,specRight(specRight)
  101.   {}
  102.  
  103.   bool is_satisfied(const Item& item) const {
  104.     return specLeft.is_satisfied(item) || specRight.is_satisfied(item);
  105.   }
  106. };
  107.  
  108. template <typename T>
  109. struct AndSpecification: Specification<T> {
  110.   const Specification<T>& specLeft;
  111.   const Specification<T>& specRight;
  112.  
  113.   AndSpecification(const Specification<T>& specLeft, const Specification<T>& specRight):
  114.     specLeft(specLeft)
  115.     ,specRight(specRight)
  116.   {}
  117.  
  118.   bool is_satisfied(const Item& item) const {
  119.     return specLeft.is_satisfied(item) && specRight.is_satisfied(item);
  120.   }
  121. };
  122.  
  123. int main()
  124. {  
  125.   auto container = ItemContainer();
  126.   container.addItem(Item("Medium Green", Size::medium, Color::green));
  127.   container.addItem(Item("Large Red", Size::large, Color::red));
  128.   container.addItem(Item("Small Blue", Size::small, Color::blue));
  129.   container.addItem(Item("Small Red", Size::small, Color::red));
  130.  
  131.   Filter<Item> genericFilter;
  132.   SizeSpecification sizeSpec(Size::small);
  133.   ColorSpecification colorSpec(Color::red);
  134.     auto filt = (colorSpec && sizeSpec)||(colorSpec || sizeSpec);
  135.   auto filteredItems = genericFilter.filter(container, filt);
  136.   for (const auto &item: filteredItems) {
  137.     std::cout << "Filtered: " << item->name << std::endl;
  138.   }
  139.  
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement