diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c39d6fa --- /dev/null +++ b/CMakeLists.txt @@ -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 +) \ No newline at end of file diff --git a/include/engine.h b/include/engine.h new file mode 100644 index 0000000..cf8bedd --- /dev/null +++ b/include/engine.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include "wrapper.h" + +class engine +{ + +public: + template + void register_cmd(wrapper* cmd, const std::string& text) + { + cmd->set_name(text); + list.push_back((void*)cmd); + }; + + template + ArgType execute(const std::string& text, + const std::vector>& args) + { + for (auto* ptr : list) + { + auto* cmd = static_cast*>(ptr); + + if (cmd->get_name() == text) + return cmd->call(args); + } + + return ArgType{}; + } + + +private: + std::vector list; +}; diff --git a/include/subject.h b/include/subject.h new file mode 100644 index 0000000..f50d23d --- /dev/null +++ b/include/subject.h @@ -0,0 +1,10 @@ +#pragma once + +class subject +{ +public: + + int sum(int a, int b); + + double multiply(double a, double b); +}; diff --git a/include/wrapper.h b/include/wrapper.h new file mode 100644 index 0000000..488e3be --- /dev/null +++ b/include/wrapper.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +template +class wrapper +{ +public: + wrapper(Obj* obj, + Method method, + const std::vector>& 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>& 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> defaultArgs; + +private: + ArgType get_value(const std::string& key, + const std::vector>& 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{}; + } +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..954063f --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,115 @@ +#include +#include +#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 wrapper( + &subj, + &subject::multiply, + { {"arg1", 2.0}, {"arg2", 1.5} } + ); + + engine engine; + engine.register_cmd(&wrapper, "mul"); + + double r = engine.execute( + "mul", + { {"arg1", 3.0} } + ); + + print_test("test_override", r, 4.5); +} + +//все лишнее игнорируем +void test_mul_ignore() +{ + subject subj; + + wrapper wrapper( + &subj, + &subject::multiply, + { {"arg1", 2.0}, {"arg2", 1.5} } + ); + + engine engine; + engine.register_cmd(&wrapper, "mul_ignore"); + + double r = engine.execute( + "mul_ignore", + { + {"argX", 999.0}, + {"arg1", 3.0} + } + ); + + + print_test("test_mul_ignore", r, 4.5); +} + +//пустой список +void test_sum_defaults() +{ + subject subj; + + wrapper wrapper( + &subj, + &subject::sum, + { {"arg1", 0}, {"arg2", 0} } + ); + + engine engine; + engine.register_cmd(&wrapper, "sum_defaults"); + + int r = engine.execute( + "sum_defaults", + {} + ); + + print_test("ttest_sum_defaults", r, 0); +} + +//суммирование где арументы явные +void test_original() +{ + subject subj; + + wrapper wrapper( + &subj, + &subject::sum, + { {"arg1", 0}, {"arg2", 0} } + ); + + engine engine; + engine.register_cmd(&wrapper, "sum"); + + int r = engine.execute( + "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; +} diff --git a/src/subject.cpp b/src/subject.cpp new file mode 100644 index 0000000..e0b866f --- /dev/null +++ b/src/subject.cpp @@ -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); +}