Advertisement
kutuzzzov

Урок 7 проще и быстрее

Dec 26th, 2022
1,822
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.87 KB | None | 0 0
  1. // main
  2.  
  3. #include "log_duration.h"
  4. #include "my_assert.h"
  5. #include "stack_vector.h"
  6.  
  7. #include <iostream>
  8. #include <random>
  9. #include <stdexcept>
  10.  
  11. using namespace std;
  12.  
  13. void TestConstruction() {
  14.     StackVector<int, 10> v;
  15.     assert(v.Size() == 0u);
  16.     assert(v.Capacity() == 10u);
  17.  
  18.     StackVector<int, 8> u(5);
  19.     assert(u.Size() == 5u);
  20.     assert(u.Capacity() == 8u);
  21.  
  22.     try {
  23.         StackVector<int, 10> u(50);
  24.         cout << "Expect invalid_argument for too large size"s << endl;
  25.         assert(false);
  26.     } catch (invalid_argument&) {
  27.     } catch (...) {
  28.         cout << "Expect invalid_argument for too large size"s << endl;
  29.         assert(false);
  30.     }
  31. }
  32.  
  33. void TestPushBack() {
  34.     StackVector<int, 5> v;
  35.     for (size_t i = 0; i < v.Capacity(); ++i) {
  36.         v.PushBack(i);
  37.     }
  38.  
  39.     try {
  40.         v.PushBack(0);
  41.         cout << "Expect overflow_error for PushBack in full vector"s << endl;
  42.         assert(false);
  43.     } catch (overflow_error&) {
  44.     } catch (...) {
  45.         cout << "Unexpected exception for PushBack in full vector"s << endl;
  46.         assert(false);
  47.     }
  48. }
  49.  
  50. void TestPopBack() {
  51.     StackVector<int, 5> v;
  52.     for (size_t i = 1; i <= v.Capacity(); ++i) {
  53.         v.PushBack(i);
  54.     }
  55.     for (int i = v.Size(); i > 0; --i) {
  56.         assert(v.PopBack() == i);
  57.     }
  58.  
  59.     try {
  60.         v.PopBack();
  61.         cout << "Expect underflow_error for PopBack from empty vector"s << endl;
  62.         assert(false);
  63.     } catch (underflow_error&) {
  64.     } catch (...) {
  65.         cout << "Unexpected exception for PopBack from empty vector"s << endl;
  66.         assert(false);
  67.     }
  68. }
  69.  
  70. int main() {
  71.     TestConstruction();
  72.     TestPushBack();
  73.     TestPopBack();
  74.  
  75.     cerr << "Running benchmark..."s << endl;
  76.     const size_t max_size = 2500;
  77.  
  78.     default_random_engine re;
  79.     uniform_int_distribution<int> value_gen(1, max_size);
  80.  
  81.     vector<vector<int>> test_data(50000);
  82.     for (auto& cur_vec : test_data) {
  83.         cur_vec.resize(value_gen(re));
  84.         for (int& x : cur_vec) {
  85.             x = value_gen(re);
  86.         }
  87.     }
  88.  
  89.     {
  90.         LOG_DURATION("vector w/o reserve");
  91.         for (auto& cur_vec : test_data) {
  92.             vector<int> v;
  93.             for (int x : cur_vec) {
  94.                 v.push_back(x);
  95.             }
  96.         }
  97.     }
  98.     {
  99.         LOG_DURATION("vector with reserve");
  100.         for (auto& cur_vec : test_data) {
  101.             vector<int> v;
  102.             v.reserve(cur_vec.size());
  103.             for (int x : cur_vec) {
  104.                 v.push_back(x);
  105.             }
  106.         }
  107.     }
  108.     {
  109.         LOG_DURATION("StackVector");
  110.         for (auto& cur_vec : test_data) {
  111.             StackVector<int, max_size> v;
  112.             for (int x : cur_vec) {
  113.                 v.PushBack(x);
  114.             }
  115.         }
  116.     }
  117.     cerr << "Done"s << endl;
  118. }
  119.  
  120. // log_duration.h
  121.  
  122. #pragma once
  123.  
  124. #include <chrono>
  125. #include <iostream>
  126.  
  127. #define PROFILE_CONCAT_INTERNAL(X, Y) X##Y
  128. #define PROFILE_CONCAT(X, Y) PROFILE_CONCAT_INTERNAL(X, Y)
  129. #define UNIQUE_VAR_NAME_PROFILE PROFILE_CONCAT(profileGuard, __LINE__)
  130. #define LOG_DURATION(x) LogDuration UNIQUE_VAR_NAME_PROFILE(x)
  131. #define LOG_DURATION_STREAM(x, y) LogDuration UNIQUE_VAR_NAME_PROFILE(x, y)
  132.  
  133. class LogDuration {
  134. public:
  135.     // заменим имя типа std::chrono::steady_clock
  136.     // с помощью using для удобства
  137.     using Clock = std::chrono::steady_clock;
  138.  
  139.     LogDuration(const std::string& id, std::ostream& dst_stream = std::cerr)
  140.         : id_(id)
  141.         , dst_stream_(dst_stream) {
  142.     }
  143.  
  144.     ~LogDuration() {
  145.         using namespace std::chrono;
  146.         using namespace std::literals;
  147.  
  148.         const auto end_time = Clock::now();
  149.         const auto dur = end_time - start_time_;
  150.         dst_stream_ << id_ << ": "s << duration_cast<milliseconds>(dur).count() << " ms"s << std::endl;
  151.     }
  152.  
  153. private:
  154.     const std::string id_;
  155.     const Clock::time_point start_time_ = Clock::now();
  156.     std::ostream& dst_stream_;
  157. };
  158.  
  159. // my_assert.h
  160.  
  161. #pragma once
  162. #include <memory>
  163. #include <string>
  164.  
  165. namespace detail {
  166.  
  167. class AssertionFailed final {
  168. public:
  169.     AssertionFailed(std::string message, std::string file, std::string func, unsigned line)
  170.         : message_{std::move(message)}
  171.         , file_{std::move(file)}
  172.         , function_{std::move(func)}
  173.         , line_(line) {
  174.     }
  175.  
  176.     const std::string& GetMessage() const {
  177.         return message_;
  178.     }
  179.  
  180.     const std::string& GetFile() const {
  181.         return file_;
  182.     }
  183.  
  184.     const std::string& GetFunction() const {
  185.         return function_;
  186.     }
  187.  
  188.     unsigned GetLine() const {
  189.         return line_;
  190.     }
  191.  
  192. private:
  193.     std::string message_;
  194.     std::string file_;
  195.     std::string function_;
  196.     unsigned line_;
  197. };
  198.  
  199. inline void AssertImpl(const char* message, char const* file, char const* func, unsigned line) {
  200.     throw AssertionFailed(message, file, func, line);
  201. }
  202.  
  203. }  // namespace detail
  204.  
  205. #ifdef assert
  206. #undef assert
  207. #endif
  208.  
  209. #define assert(expression)   \
  210.     (void) ((!!(expression)) \
  211.             || (::detail::AssertImpl(#expression, __FILE__, __FUNCTION__, static_cast<unsigned>(__LINE__)), 0))
  212.  
  213. // stack_vector.h
  214.  
  215. #pragma once
  216.  
  217. #include <array>
  218. #include <stdexcept>
  219. #include <exception>
  220.  
  221. template <typename T, size_t N>
  222. class StackVector {
  223. public:
  224.     explicit StackVector(size_t a_size = 0) {
  225.         if (a_size > Capacity() ) {
  226.             throw std::invalid_argument("invalid_argument");
  227.         }
  228.         size_ = a_size;
  229.     }
  230.  
  231.     T& operator[](size_t index) {
  232.         return array_[index];
  233.     }
  234.  
  235.     const T& operator[](size_t index) const {
  236.         return array_[index];
  237.     }
  238.  
  239.     typename std::array<T, N>::iterator begin() noexcept {
  240.         return array_.begin();
  241.     }
  242.  
  243.     typename std::array<T, N>::iterator end() noexcept {
  244.         auto it_first = array_.begin();
  245.         auto it_last = size_;
  246.         auto nx = std::next(it_first, it_last);
  247.         return nx;
  248.     }
  249.  
  250.     typename std::array<T, N>::const_iterator begin() const noexcept {
  251.         return array_.begin();
  252.     }
  253.  
  254.     typename std::array<T, N>::const_iterator end() const noexcept {
  255.         auto it_first = array_.begin();
  256.         auto it_last = size_;
  257.         auto nx = std::next(it_first, it_last);
  258.         return nx;
  259.     }
  260.  
  261.     size_t Size() const {
  262.         return size_;
  263.     }
  264.     size_t Capacity() const {
  265.         return array_.size();
  266.     }
  267.  
  268.     void PushBack(const T& value) {
  269.         if (size_ == Capacity()) {
  270.             throw std::overflow_error("no space");
  271.         } else {
  272.             array_[size_] = value;
  273.             ++size_;
  274.         }
  275.     }
  276.  
  277.     T PopBack() {
  278.         if (size_ == 0) {
  279.             throw std::underflow_error("no elements");
  280.         } else {
  281.             --size_;
  282.             return array_[size_];
  283.         }
  284.     }
  285.  
  286. private:
  287.     std::array<T, N> array_;
  288.     size_t size_{};
  289. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement