shushus

Спринт 13. Не очень чистые функции - побочные эффекты.

Apr 20th, 2023
433
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.10 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <optional>
  4. #include <string_view>
  5. #include <utility>
  6. #include <vector>
  7.  
  8. using namespace std;
  9.  
  10. template <typename InputIt, typename OutSum, typename OutSqSum, typename OutMax>
  11. void ComputeStatistics(InputIt first,
  12.                        InputIt last,
  13.                        OutSum& out_sum,
  14.                        OutSqSum& out_sq_sum,
  15.                        OutMax& out_max) {
  16.    
  17.     using Elem = std::decay_t<decltype(*first)>;
  18.  
  19.     constexpr bool need_sum = !is_same_v<OutSum, const nullopt_t>;
  20.     constexpr bool need_sq_sum = !is_same_v<OutSqSum, const nullopt_t>;
  21.     constexpr bool need_max = !is_same_v<OutMax, const nullopt_t>;
  22.  
  23.     optional<Elem> sum, sq_sum, max_elem;
  24.     size_t count = 0;
  25.  
  26.     for (auto it = first; it != last; ++it, ++count) {
  27.        
  28.         if constexpr (need_sum) {
  29.             !sum ? sum = *it : *sum += *it;
  30.         }
  31.        
  32.         if constexpr (need_sq_sum) {
  33.             !sq_sum ? sq_sum = *it * *it : *sq_sum += *it * *it;
  34.         }
  35.        
  36.         if constexpr (need_max) {
  37.             !max_elem ? max_elem = *it : max_elem = max(*max_elem, *it);
  38.         }
  39.        
  40.     }
  41.  
  42.     if constexpr (need_sum) {
  43.         if (sum) {
  44.             out_sum = *sum;
  45.         }
  46.     }
  47.    
  48.     if constexpr (need_sq_sum) {
  49.         if (sq_sum) {
  50.             out_sq_sum = *sq_sum;
  51.         }
  52.     }
  53.    
  54.     if constexpr (need_max) {
  55.         if (max_elem) {
  56.             out_max = *max_elem;
  57.         }
  58.     }
  59. }
  60.  
  61. struct OnlySum {int value;};
  62. OnlySum operator+(OnlySum l, OnlySum r) {return {l.value + r.value};}
  63. OnlySum& operator+=(OnlySum& l, OnlySum r) {return l = l + r;}
  64.  
  65. int main() {
  66.     vector input = {1, 2, 3, 4, 5, 6};
  67.     int sq_sum;
  68.     std::optional<int> max;
  69.  
  70.     ComputeStatistics(input.begin(), input.end(), nullopt, sq_sum, max);
  71.  
  72.     assert(sq_sum == 91 && max && *max == 6);
  73.  
  74.     vector<OnlySum> only_sum_vector = {{100}, {-100}, {20}};
  75.     OnlySum sum;
  76.  
  77.     ComputeStatistics(only_sum_vector.begin(), only_sum_vector.end(), sum, nullopt, nullopt);
  78.  
  79.     assert(sum.value == 20);
  80. }
Advertisement
Add Comment
Please, Sign In to add comment