#include
#include
#include
#include
using namespace std;
// 反射相关
class funcValidPolicy {
public:
template
static false_type Valid(...);
template()(declval()...))>
static true_type Valid(void *);
};
template
struct TypeT {
using type = T;
};
template
constexpr auto type = TypeT{};
template
T ValueT(TypeT);
auto is_valid = [](auto f) {
return [](auto ...args) {
return decltype(funcValidPolicy::template Valid(nullptr)){};
//return isInvokeAble::value;
};
};
// 类型必须要getInstance函数
auto has_getInstance = is_valid([](auto t) -> decltype(decltype(ValueT(t))::getInstance()) {
});
string doubleToStr(double price) {
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.2lf", price);
return buffer;
}
string descriptionFormat(const string &name, double price) {
return "with " + name + "(" + doubleToStr(price) + ")n";
}
#define shared_instance_func(name)
static shared_ptr getInstance() {
return shared_ptr(new name);
}
#define DecoratorDefaultFunc(name)
private:
shared_ptr beverage;
explicit name(Beverage* bev = nullptr) : beverage(bev){}
public:
void setBeverage(const shared_ptr& bev) override{
beverage = bev;
}
shared_instance_func(name)
class Decorator;
class Beverage : public enable_shared_from_this {
public:
string _description;
virtual string getDescription() {
return _description + "(" + doubleToStr(totalCost()) + ")n";
}
virtual double totalCost() = 0;
virtual ~Beverage() = default;
virtual void setBeverage(const shared_ptr &) {}
template> &&
has_getInstance(type)
>>
auto withDecorator();
template> &&
has_getInstance(type)
>>
auto withDecorator(shared_ptr);
};
// 抽象类,带数据
class Decorator : public Beverage {
public:
//
string getDescription() override = 0;
double totalCost() override = 0;
virtual double cost() = 0;
};
template
auto Beverage::withDecorator() {
auto beverage = T::getInstance();
beverage->setBeverage(shared_from_this());
return beverage;
}
template
auto Beverage::withDecorator(shared_ptr beverage) {
beverage->setBeverage(shared_from_this());
return beverage;
}
class Espresso : public Beverage {
private:
Espresso() {
_description = "Espresso";
}
public:
shared_instance_func(Espresso)
double totalCost() override {
return 1.99;
}
};
class Mocha : public Decorator {
public:
DecoratorDefaultFunc(Mocha)
string getDescription() override {
assert(nullptr != beverage);
return beverage->getDescription() + descriptionFormat("Mocha", cost());
}
double totalCost() override {
assert(nullptr != beverage);
return beverage->totalCost() + cost();
}
double cost() override {
return .32;
}
};
class Whip : public Decorator {
public:
DecoratorDefaultFunc(Whip)
string getDescription() override {
return beverage->getDescription() + descriptionFormat("Whip", cost());
}
double totalCost() override {
return beverage->totalCost() + cost();
}
double cost() override {
return .23;
}
};
class NoGetInstance : public Decorator {
public:
string getDescription() override {
return Decorator::getDescription();
}
double totalCost() override {
return Decorator::totalCost();
}
double cost() override {
return 0;
}
};
int main() {
// 用法一
auto a = Espresso::getInstance();
auto ab = a->withDecorator()->withDecorator()->withDecorator();
cout << ab->getDescription() << "total : ";
cout << ab->totalCost() << endl << endl;
// 用法二
auto d = Espresso::getInstance();
auto de = d->withDecorator(Mocha::getInstance())->withDecorator(Whip::getInstance())->withDecorator(
Mocha::getInstance());
cout << de->getDescription() << "total : ";
cout << de->totalCost() << endl;
}