diff --git a/Chaos/Service/SeArray.hpp b/Chaos/Service/SeArray.hpp new file mode 100644 index 0000000..280ae0d --- /dev/null +++ b/Chaos/Service/SeArray.hpp @@ -0,0 +1,92 @@ +#ifndef CHAOS_SERVICE_SEARRAY_HPP +#define CHAOS_SERVICE_SEARRAY_HPP + +#include +#include + +namespace Chaos::Service +{ + +template>> +class SeArray +{ +public: + SeArray() + { + Storage_.fill(0); + } + + SeArray(const SeArray & other) = delete; + SeArray(SeArray && other) = delete; + + SeArray & operator=(const SeArray & other) = delete; + SeArray & operator=(SeArray && other) = delete; + + ~SeArray() + { + EraseImpl(); + } + + T & operator[](size_t pos) + { + return Storage_[pos]; + } + + const T & operator[](size_t pos) const + { + return Storage_[pos]; + } + + T * Begin() noexcept + { + return Storage_.data(); + } + + const T * Begin() const noexcept + { + return Storage_.data(); + } + + T * End() noexcept + { + return Storage_.data() + Storage_.size(); + } + + const T * End() const noexcept + { + return Storage_.data() + Storage_.size(); + } + + constexpr size_t Size() const noexcept + { + return Storage_.size(); + } + + void Fill(const T & value) + { + Storage_.fill(value); + } + + void Erase() + { + EraseImpl(); + } + +private: + std::array Storage_; + + void EraseImpl() + { + volatile T * ptr = Storage_.data(); + + for (size_t i = 0; i < Storage_.size(); ++i) + { + *ptr++ = 0; + } + } +}; + +} // namespace Chaos::Service + +#endif diff --git a/ChaosTests/CMakeLists.txt b/ChaosTests/CMakeLists.txt index 17cc700..d484fc0 100644 --- a/ChaosTests/CMakeLists.txt +++ b/ChaosTests/CMakeLists.txt @@ -14,7 +14,8 @@ FetchContent_MakeAvailable(googletest) set(ChaosTests_SOURCE Hash/Md4HasherTests.cpp Hash/Md5HasherTests.cpp Mac/HmacTests.cpp - Cipher/Arc4GenTests.cpp) + Cipher/Arc4GenTests.cpp + Service/SeArrayTests.cpp) add_executable(ChaosTests ${ChaosTests_SOURCE}) target_link_libraries(ChaosTests gtest gtest_main) diff --git a/ChaosTests/Service/SeArrayTests.cpp b/ChaosTests/Service/SeArrayTests.cpp new file mode 100644 index 0000000..aa08a12 --- /dev/null +++ b/ChaosTests/Service/SeArrayTests.cpp @@ -0,0 +1,255 @@ +#include +#include +#include + +#include "Service/SeArray.hpp" + +using namespace Chaos::Service; + +TEST(SeArrayTests, InitializationTest) +{ + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } + + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } + + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } +} + +TEST(SeArrayTests, EraseTest) +{ + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + arr[i] = 1; + } + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(1, arr[i]); + } + + arr.Erase(); + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } + + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + arr[i] = 15; + } + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(15, arr[i]); + } + + arr.Erase(); + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } + + { + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + arr[i] = -1; + } + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(-1, arr[i]); + } + + arr.Erase(); + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + } +} + +TEST(SeArrayTests, SubscriptOperatorTest) +{ + SeArray arr; + + arr[0] = 10; + ASSERT_EQ(10, arr[0]); + + arr[0] = 7; + ASSERT_EQ(7, arr[0]); + + arr[arr.Size() - 1] = 99; + ASSERT_EQ(99, arr[arr.Size() - 1]); + + for (int32_t i = 0; i < arr.Size(); ++i) + { + arr[i] = i; + } + + for (int32_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(i, arr[i]); + } + + const SeArray & arrRef = arr; + + for (int32_t i = 0; i < arrRef.Size(); ++i) + { + ASSERT_EQ(i, arrRef[i]); + } +} + +TEST(SeArrayTests, IteratorsTest) +{ + SeArray arr; + + ASSERT_EQ(arr.Size(), std::distance(arr.Begin(), arr.End())); + + for (auto it = arr.Begin(); it != arr.End(); ++it) + { + ASSERT_EQ(0, *it); + } + + { + int32_t counter = 0; + + for (auto it = arr.Begin(); it != arr.End(); ++it) + { + *it = counter++; + } + + counter = 0; + + for (auto it = arr.Begin(); it != arr.End(); ++it) + { + ASSERT_EQ(counter++, *it); + } + } + + { + int32_t counter = 0; + + for (auto it = arr.Begin(); it != arr.End(); ++it) + { + *it = arr.Size() - 1 - counter++; + } + + counter = 0; + + for (auto it = std::make_reverse_iterator(arr.End()); + it != std::make_reverse_iterator(arr.Begin()); ++it) + { + ASSERT_EQ(counter++, *it); + } + } + + { + int32_t counter = 0; + + for (auto it = arr.Begin(); it != arr.End(); ++it) + { + *it = counter++; + } + + counter = 0; + const SeArray & arrRef = arr; + + for (auto it = arrRef.Begin(); it != arrRef.End(); ++it) + { + ASSERT_EQ(counter++, *it); + } + } +} + +TEST(SeArrayTests, SizeTest) +{ + { + constexpr size_t SIZE = 10; + + SeArray arr; + ASSERT_EQ(SIZE, arr.Size()); + } + + { + constexpr size_t SIZE = 20; + + SeArray arr; + ASSERT_EQ(SIZE, arr.Size()); + } + + { + constexpr size_t SIZE = 237; + + SeArray arr; + ASSERT_EQ(SIZE, arr.Size()); + } + + { + constexpr size_t SIZE = 100; + + SeArray arr; + ASSERT_EQ(SIZE, arr.Size()); + + arr.Erase(); + + ASSERT_EQ(SIZE, arr.Size()); + } +} + +TEST(SeArrayTests, FillTest) +{ + SeArray arr; + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(0, arr[i]); + } + + arr.Fill(112); + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(112, arr[i]); + } + + arr.Fill(-3); + + for (size_t i = 0; i < arr.Size(); ++i) + { + ASSERT_EQ(-3, arr[i]); + } +}