diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af67b40 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vs +05_hw/.vscode +05_hw/benchmark +05_hw/build \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..5416071 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,7 +1,58 @@ +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_compile_options(-std=c++17 -D_GLIBCXX_USE_C99 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++) + cmake_minimum_required(VERSION 3.10) project(stack) -add_library(stack stack.c) -add_executable(main main.c) +find_package(GTest REQUIRED) + + +if(WIN32) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +endif() + +add_library(stack stack.cpp) + +add_executable(main main.cpp) target_link_libraries(main stack) + +add_executable(tests tests.cpp) +target_link_libraries(tests PRIVATE gtest stack) +target_link_libraries(stack PRIVATE gcov) + +if(CMAKE_EXPORT_COMPILE_COMMANDS) + find_program(CLANG_EXECUTABLE "C:/msys64/mingw64/bin/clang.exe") + add_custom_target(analyze + COMMAND + analyze-build --cdb ${PROJECT_BINARY_DIR}/compile_commands.json + --use-analyzer ${CLANG_EXECUTABLE} + --output ${PROJECT_BINARY_DIR}/analyzer + ) +endif() + +target_compile_options(tests PRIVATE --coverage) +target_link_options(tests PRIVATE --coverage) +target_compile_options(stack PRIVATE --coverage) +target_link_options(stack PRIVATE --coverage) + + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(tests PRIVATE -fsanitize=address -fno-omit-frame-pointer) + target_link_options(tests PRIVATE -fsanitize=address) +endif() + +enable_testing() +# add_test(NAME tests COMMAND tests) +add_test(NAME stack_tests COMMAND tests) + + +set(BENCHMARK_ENABLE_TESTING OFF) +add_subdirectory(benchmark) +include_directories(benchmark/include) + +add_executable(bm bm.cpp) +target_link_libraries(bm PRIVATE benchmark::benchmark stack) diff --git a/05_hw/bm.cpp b/05_hw/bm.cpp new file mode 100644 index 0000000..c711a4d --- /dev/null +++ b/05_hw/bm.cpp @@ -0,0 +1,55 @@ +#include +#include "stack.h" + +class StackBench : public benchmark::Fixture +{ + void SetUp(::benchmark::State& state) + { + stack = new Stack(); + } + + void TearDown(::benchmark::State& state) + { + delete stack; + } + +public: + Stack* stack; +}; + +BENCHMARK_DEFINE_F(StackBench, PushBench)(benchmark::State& st) +{ + for (auto _ : st) + { + for (int i = 0; i < st.range(0); i++) + push(stack, i); + } +} + +BENCHMARK_DEFINE_F(StackBench, PopBench)(benchmark::State& st) +{ + for (int i = 0; i < st.range(0); i++) + push(stack, i); + + for (auto _ : st) + { + for (int i = 0; i < st.range(0); i++) + pop(stack); + } +} + +BENCHMARK_REGISTER_F(StackBench, PushBench) +->Arg(100) +->Arg(1000) +->Arg(10000) +->Arg(100000) +->Arg(1000000); + +BENCHMARK_REGISTER_F(StackBench, PopBench) +->Arg(100) +->Arg(1000) +->Arg(10000) +->Arg(100000) +->Arg(1000000); + +BENCHMARK_MAIN(); diff --git a/05_hw/main.c b/05_hw/main.cpp similarity index 99% rename from 05_hw/main.c rename to 05_hw/main.cpp index fded814..b1c285c 100644 --- a/05_hw/main.c +++ b/05_hw/main.cpp @@ -30,6 +30,7 @@ int main() { printf("Top element: %d\n", topElement->data); } + return 0; } diff --git a/05_hw/stack.c b/05_hw/stack.cpp similarity index 89% rename from 05_hw/stack.c rename to 05_hw/stack.cpp index 0964440..d8efb2f 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.cpp @@ -15,12 +15,8 @@ void initStack(Stack* stack) { } void destroyStack(Stack* stack) { - Node* current = stack->top; - while (current != NULL) { - Node *tmp = current; - current = current->next; - free(tmp); - } + while (stack->top != NULL) + pop(stack); } void push(Stack* stack, int data) { @@ -31,7 +27,12 @@ void push(Stack* stack, int data) { void pop(Stack* stack) { Node* temp = stack->top; - stack->top = stack->top->next; + if (temp!=NULL) { + stack->top = stack->top->next; + free(temp); + } else { + return; + } } Node* searchByValue(Stack* stack, int value) { @@ -40,6 +41,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } @@ -72,7 +74,6 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; } diff --git a/05_hw/tests.cpp b/05_hw/tests.cpp new file mode 100644 index 0000000..14ad63e --- /dev/null +++ b/05_hw/tests.cpp @@ -0,0 +1,100 @@ +#include +#include "stack.h" + +using namespace std; + +class StackTest : public testing::Test +{ + void SetUp() override + { + stack = new Stack(); + } + + void TearDown() override { + delete stack; + } + +public: + Stack* stack; +}; + +TEST_F(StackTest, initStackTest) { + Stack f; + initStack(&f); + EXPECT_EQ(isEmpty(&f), true); +} + +TEST_F(StackTest, isEmptyTest) { + EXPECT_EQ(isEmpty(stack), true); +} + +TEST_F(StackTest, pushTest) { + push(stack, 44); + EXPECT_EQ(getTop(stack)->data, 44); +} + +TEST_F(StackTest, popTest) { + push(stack, 0); + push(stack, 3); + push(stack, 11); + pop(stack); + EXPECT_EQ(getTop(stack)->data, 3); +} + +TEST_F(StackTest, EmptyPopTest) { + pop(stack); + EXPECT_EQ(getTop(stack), nullptr); +} + + +TEST_F(StackTest, destroyStackTests) { + push(stack, -12); + push(stack, -31); + push(stack, 2); + push(stack, 832); + + destroyStack(stack); + + EXPECT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, searchByValueTest) { + push(stack, 12); + push(stack, -2); + push(stack, 72); + + EXPECT_EQ(searchByValue(stack, -2)->data, -2); +} + +TEST_F(StackTest, searchByIndexTest) { + push(stack, 12); + push(stack, 2); + push(stack, 72); + + EXPECT_EQ(searchByIndex(stack, 2)->data, 12); +} + +TEST_F(StackTest, traverseStackTest) { + testing::internal::CaptureStdout(); + + push(stack, 22129); + push(stack, -12); + push(stack, 0); + push(stack, 51242); + push(stack, -33); + + traverseStack(stack); + + std::string expected = "Stack elements: -33 51242 0 -12 22129 \n"; + std::string output = testing::internal::GetCapturedStdout(); + + EXPECT_EQ(expected, output); +} + + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 610bb77..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# Читать README в 05_hw