#include #include #include using namespace std; enum ProductColor { Red, Green, Blue, Cyan, Magenta, Yellow, White, Black }; class Product { public: string Name; float Price; float Weight; ProductColor Color; Product(string name, float price, float weight, ProductColor color) { Name = name; Price = price; Weight = weight; Color = color; } void Show(){ cout< ProductList; class Spec{ public: virtual bool isSatisfiedBy(Product& p)=0; }; class ColorSpec:public Spec { ProductColor Color; public: ColorSpec(ProductColor color):Color(color){ } bool isSatisfiedBy(Product& p) { return (Color == p.Color); } }; class BelowPriceSpec:public Spec { float ThreasholdPrice; public: BelowPriceSpec(float thPrice) { ThreasholdPrice = thPrice; } bool isSatisfiedBy(Product& p) { return p.Price < ThreasholdPrice; } }; class NotSpec:public Spec { Spec *specToNegate=0; public: NotSpec(Spec& spec) { specToNegate = &spec; } bool isSatisfiedBy(Product& p) { return !specToNegate->isSatisfiedBy(p); } }; class AndSpec:public Spec { Spec *plhs, *prhs; public: AndSpec(Spec& lhs, Spec& rhs) { plhs = &lhs; prhs = &rhs; } bool isSatisfiedBy(Product& p) { return plhs->isSatisfiedBy(p) && prhs->isSatisfiedBy(p); } }; class OrSpec:public Spec { Spec *plhs, *prhs; public: OrSpec(Spec& lhs, Spec& rhs) { plhs = &lhs; prhs = &rhs; } bool isSatisfiedBy(Product& p) { return plhs->isSatisfiedBy(p) || prhs->isSatisfiedBy(p); } }; class ProductFinder { ProductList *products=0; public: ProductFinder(ProductList& ps) { products = &ps; } ProductList* by(Spec& spec) { auto selected = new ProductList(); for(auto &pp : *products){ if (spec.isSatisfiedBy(*pp)) selected->push_back(pp); } return selected; } ProductList *byColor(ProductColor color) { ColorSpec colorSpec(color); return by(colorSpec); } ProductList *byColorAndBelowPrice(ProductColor color, float price) { ColorSpec colorSpec(color); BelowPriceSpec belowPriceSpec(price); AndSpec andSpec(colorSpec,belowPriceSpec); return by(andSpec); } ProductList* byBelowPriceAvoidingAColor(float price, ProductColor color) { BelowPriceSpec belowPriceSpec(price); ColorSpec colorSpec(color); NotSpec notSpec(colorSpec); AndSpec andSpec(belowPriceSpec,notSpec); return by(andSpec); } ProductList* byAll(vector& specs) { auto selected = new ProductList(); for(auto &pp : *products){ for(auto &spec : specs){ int i; for(i=0;iisSatisfiedBy(*pp)) break; } if(i==specs.size()) selected->push_back(pp); } } return selected; } ProductList* byAny(vector& specs) { auto selected = new ProductList(); for(auto &pp : *products){ for(auto &pspec : specs){ if (pspec->isSatisfiedBy(*pp)){ selected->push_back(pp); break; } } } } }; static void showBlueProducts(ProductFinder& pf) { ProductList *pproducts = pf.byColor(Blue); for(auto &p : *pproducts) p->Show(); delete pproducts; } int main() { Product A("A", 20, 0.56F, Blue); Product B("B", 25, 1.66F, Green); Product C("C", 17, 0.56F, Blue); Product D("D", 29, 2.47F, Red); Product E("E", 31, 3.53F, Black); Product F("F", 22, 0.66F, Green); Product G("G", 14, 4.12F, Blue); ProductList products{&A, &B, &C, &D, &E, &F, &G}; ProductFinder pf(products); showBlueProducts(pf); return 0; }