Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.30)
project(CPP_Lab_2)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(CPP_Lab_2 src/main.cpp src/subject.cpp)

target_include_directories(CPP_Lab_2 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
36 changes: 36 additions & 0 deletions include/engine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <string>
#include <vector>
#include "wrapper.h"

class engine
{

public:
template<typename Obj, typename Method, typename ArgType>
void register_cmd(wrapper<Obj, Method, ArgType>* cmd, const std::string& text)
{
cmd->set_name(text);
list.push_back((void*)cmd);
};

template<typename Obj, typename Method, typename ArgType>
ArgType execute(const std::string& text,
const std::vector<std::pair<std::string, ArgType>>& args)
{
for (auto* ptr : list)
{
auto* cmd = static_cast<wrapper<Obj, Method, ArgType>*>(ptr);

if (cmd->get_name() == text)
return cmd->call(args);
}

return ArgType{};
}


private:
std::vector<void*> list;
};
10 changes: 10 additions & 0 deletions include/subject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

class subject
{
public:

int sum(int a, int b);

double multiply(double a, double b);
};
62 changes: 62 additions & 0 deletions include/wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <string>
#include <vector>

template<typename Obj, typename Method, typename ArgType>
class wrapper
{
public:
wrapper(Obj* obj,
Method method,
const std::vector<std::pair<std::string, ArgType>>& defaults)
: objectRef(obj),
methodRef(method),
defaultArgs(defaults)
{
}

void set_name(const std::string& text)
{
name = text;
}
const std::string& get_name() const
{
return name;
}

ArgType call(const std::vector<std::pair<std::string, ArgType>>& args)
{
ArgType a = get_value("arg1", args);
ArgType b = get_value("arg2", args);

return std::invoke(methodRef, objectRef, a, b);
}

private:
std::string name;

Obj* objectRef;
Method methodRef;

std::vector<std::pair<std::string, ArgType>> defaultArgs;

private:
ArgType get_value(const std::string& key,
const std::vector<std::pair<std::string, ArgType>>& args)
{
for (const auto& p : args)
{
if (p.first == key)
return p.second;
}

for (const auto& p : defaultArgs)
{
if (p.first == key)
return p.second;
}

return ArgType{};
}
};
115 changes: 115 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include <iostream>
#include <string>
#include "subject.h"
#include "wrapper.h"
#include "engine.h"

void print_test(const std::string& name, double result, double expected)
{
std::cout << name << ": результат = " << result
<< ", ожидается = " << expected << std::endl;
}


//переопределение arg1
void test_override()
{
subject subj;

wrapper<subject, double(subject::*)(double, double), double> wrapper(
&subj,
&subject::multiply,
{ {"arg1", 2.0}, {"arg2", 1.5} }
);

engine engine;
engine.register_cmd<subject, double(subject::*)(double, double), double>(&wrapper, "mul");

double r = engine.execute<subject, double(subject::*)(double, double), double>(
"mul",
{ {"arg1", 3.0} }
);

print_test("test_override", r, 4.5);
}

//все лишнее игнорируем
void test_mul_ignore()
{
subject subj;

wrapper<subject, double(subject::*)(double, double), double> wrapper(
&subj,
&subject::multiply,
{ {"arg1", 2.0}, {"arg2", 1.5} }
);

engine engine;
engine.register_cmd<subject, double(subject::*)(double, double), double>(&wrapper, "mul_ignore");

double r = engine.execute<subject, double(subject::*)(double, double), double>(
"mul_ignore",
{
{"argX", 999.0},
{"arg1", 3.0}
}
);


print_test("test_mul_ignore", r, 4.5);
}

//пустой список
void test_sum_defaults()
{
subject subj;

wrapper<subject, int(subject::*)(int, int), int> wrapper(
&subj,
&subject::sum,
{ {"arg1", 0}, {"arg2", 0} }
);

engine engine;
engine.register_cmd<subject, int(subject::*)(int, int), int>(&wrapper, "sum_defaults");

int r = engine.execute<subject, int(subject::*)(int, int), int>(
"sum_defaults",
{}
);

print_test("ttest_sum_defaults", r, 0);
}

//суммирование где арументы явные
void test_original()
{
subject subj;

wrapper<subject, int(subject::*)(int, int), int> wrapper(
&subj,
&subject::sum,
{ {"arg1", 0}, {"arg2", 0} }
);

engine engine;
engine.register_cmd<subject, int(subject::*)(int, int), int>(&wrapper, "sum");

int r = engine.execute<subject, int(subject::*)(int, int), int>(
"sum",
{ {"arg1", 4}, {"arg2", 5} }
);

print_test("test_original", r, 9);
}


int main()
{
test_override();
test_mul_ignore();
test_sum_defaults();
test_original();

return 0;
}
11 changes: 11 additions & 0 deletions src/subject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "subject.h"

int subject::sum(int a, int b)
{
return a + b;
}

double subject::multiply(double a, double b)
{
return (a * b);
}