Когда речь идет о создании соответствующего движка, в основном для Exchange или DarkPool в торговой зоне, нам обычно нужно проверять, могут ли 2 ордера совпадать или нет (или мы говорим, могут пересекаться или нет), может быть много аспектов, чтобы проверить, какиемы называем Правила , и вот основные требования к организации этих правил:
- Должно быть легко добавить новое правило и получить применение
- Должно быть удобно организовывать правила в разные группы для применения проверок
- Поскольку проверка правил вызывается довольно часто - ну, конечно, это единственная работа соответствующего механизма, мы хотим, чтобы он был оптимальнымнасколько это возможно
Это прекрасно подходит для использования boost mpl, который может использовать последовательность времени компиляции boost::mpl::vector
для организации правил и применять их с помощью boost::mpl::for_each
.
.Идея лучше всего проиллюстрирована на примере:
- Добавить новое правило просто, просто определив новый класс правил
- Удобно группироватьЕсли вы используете
boost::mpl::vector
и используете его в качестве параметра шаблона для canCross
check - Поскольку большая часть работы по настройке выполняется во время компиляции, это быстро.
#include <iostream>
#include <vector>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
using namespace std;
struct Order {};
struct Rule1
{
const char* name() const { return "Rule1"; }
bool apply(const Order& a, const Order& b) const { cout << "Checking Rule1..." << endl; return true; }
};
struct Rule2
{
const char* name() const { return "Rule2"; }
bool apply(const Order& a, const Order& b) const { cout << "Checking Rule2..." << endl; return false;}
};
struct Rule3
{
const char* name() const { return "Rule3"; }
bool apply(const Order& a, const Order& b) const { cout << "Checking Rule3..." << endl; return false;}
};
struct Rule4
{
const char* name() const { return "Rule4"; }
bool apply(const Order& a, const Order& b) const { cout << "Checking Rule4..." << endl; return true;}
};
struct RuleApplicator
{
RuleApplicator(bool& success, std::vector<const char*>& failedRules, const Order& order1, const Order& order2):
_success(success),
_failedRules(failedRules),
_order1(order1),
_order2(order2)
{}
template <typename U> void operator() (U rule)
{
if(!rule.apply(_order1, _order2))
{
_success = false;
_failedRules.push_back(rule.name());
}
}
private:
bool& _success;
std::vector<const char*>& _failedRules;
const Order& _order1;
const Order& _order2;
};
template <class Rules>
bool canCross(const Order& a, const Order& b)
{
bool success = true;
std::vector<const char*> failedRules;
RuleApplicator applicator(success, failedRules, a, b);
boost::mpl::for_each<Rules>(applicator);
if (!success)
{
cout << "Can't cross due to rule check failure:";
for(const char* ruleName: failedRules)
{
cout << ruleName << " ";
}
cout << endl;
return false;
}
else
{
cout << "Can cross!" << endl;
return true;
}
}
int main(int argc, char** argv)
{
Order a, b;
canCross<boost::mpl::vector<Rule1, Rule4>>(a, b);
cout << endl;
canCross<boost::mpl::vector<Rule1, Rule2, Rule3, Rule4>>(a, b);
}
Вы увидите вывод:
Checking Rule1...
Checking Rule4...
Can cross!
Checking Rule1...
Checking Rule2...
Checking Rule3...
Checking Rule4...
Can't cross due to rule check failure:Rule2 Rule3