Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <typeinfo>
- #include <typeindex>
- #include <unordered_map>
- #include <utility>
- #include <functional>
- struct pair_hash {
- template <class T1, class T2>
- std::size_t operator () (const std::pair<T1,T2> &p) const {
- auto h1 = std::hash<T1>{}(p.first);
- auto h2 = std::hash<T2>{}(p.second);
- return h1 ^ h2; //XOR
- }
- };
- template <class T, class R, bool Commutative>
- class Multimethod2
- {
- public:
- using Index = std::pair< std::type_index, std::type_index>;
- using F = std::function<R(T *, T *)>;
- using Unordered_map = std::unordered_map<Index, F, pair_hash>;
- Unordered_map mF;
- Multimethod2() {}
- void addImpl( const std::type_info &l, const std::type_info &r, F f) {
- mF[std::make_pair(std::type_index(l),std::type_index(r))] = f;
- // if (l != r)
- // if (Commutative) mF[std::make_pair(std::type_index(r),std::type_index(l))] = f;
- }
- bool hasImpl(T* l, T* r) const {
- if ( mF.find({std::type_index(typeid(*l)), std::type_index(typeid(*r))}) != mF.end() )
- return true;
- if (Commutative)
- if ( mF.find({std::type_index(typeid(*r)), std::type_index(typeid(*l))}) != mF.end() )
- return true;
- return false;
- }
- R call(T* l, T* r) const {
- auto it = mF.find({std::type_index(typeid(*l)), std::type_index(typeid(*r))});
- if (it !=mF.end()) {
- return (it->second)(l,r);
- }
- if (Commutative) {
- it = mF.find({std::type_index(typeid(*l)), std::type_index(typeid(*r))});
- if (it !=mF.end()) {
- return (it->second)(l,r);
- }
- }
- return R();
- }
- };
- ///////////////
- #include <iostream>
- #include <typeinfo>
- #include <typeindex>
- #include <unordered_map>
- #include <multimetod.h>
- #include <string>
- using namespace std;
- // базовый класс фигуры (полиморфный)
- struct Shape {
- public:
- virtual ~Shape() = 0;
- };
- Shape::~Shape() {}
- // прямоугольник
- struct Rectangle : Shape {
- Rectangle(int x, int y, int x2, int y2) :
- x(x), y(y), x2(x2), y2(y2) { }
- Rectangle() : Rectangle(4,4,4,4) {}
- int x;
- int y;
- int x2;
- int y2;
- ~Rectangle() {}
- };
- // треугольник
- struct Triangle : Shape
- {
- Triangle(int x, int y, int x2) :
- x(x), y(y), x2(x2) { }
- Triangle(): Triangle(3,3,3){}
- int x;
- int y;
- int x2;
- ~Triangle() {}
- };
- void f1( Triangle t) {
- std::cout << __func__ << std::endl;
- }
- void f2( Rectangle r) {
- std::cout << __func__ << std::endl;
- }
- // функция для проверки пересечения двух прямоугольников
- std::string is_intersect_r_r(Shape * a, Shape * b) {
- std::cout << __func__;
- return "is_intersect_r_r";}
- // функция для проверки пересечения прямоугольника и треугольника
- std::string is_intersect_r_t(Shape * a, Shape * b) {
- std::cout << __func__;
- return "is_intersect_r_t";}
- void is_intersect_r_t_v(Shape * a, Shape * b) {
- std::cout << __func__;
- }
- int main()
- {
- Shape *t1 = new Triangle();
- Shape *t2 = new Triangle();
- Shape* t3 = new Rectangle();
- {
- Multimethod2<Shape, void, true> is_intersect;
- is_intersect.addImpl(typeid(Rectangle), typeid(Rectangle), is_intersect_r_t_v);
- Shape * s1 = new Rectangle();
- Shape * s2 = new Triangle();
- if (is_intersect.hasImpl(s1, s2))
- {
- std::cout << "true\n";
- // вызывается функция is_intersect_r_t(s2, s1)
- is_intersect.call(s1, s2);
- // Замечание: is_intersect_r_t ожидает,
- // что первым аргументом будет прямоугольник
- // а вторым треугольник, а здесь аргументы
- // передаются в обратном порядке.
- // ваша реализация должна самостоятельно
- // об этом позаботиться
- }
- }
- Multimethod2<Shape, std::string, true> is_intersect;
- is_intersect.addImpl(typeid(Rectangle), typeid(Rectangle), is_intersect_r_r);
- is_intersect.addImpl(typeid(Rectangle), typeid(Triangle), is_intersect_r_t);
- Shape * s1 = new Rectangle();
- Shape * s2 = new Triangle();
- if (is_intersect.hasImpl(s2, s1))
- {
- std::cout << true;
- // вызывается функция is_intersect_r_t(s2, s1)
- auto res = is_intersect.call(s2, s1);
- std::cout << res;
- // Замечание: is_intersect_r_t ожидает,
- // что первым аргументом будет прямоугольник
- // а вторым треугольник, а здесь аргументы
- // передаются в обратном порядке.
- // ваша реализация должна самостоятельно
- // об этом позаботиться
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment