Auxiliary Arithmetic Algorithms
divide.hpp
1 #pragma once
2 
3 #include <algorithm>
4 
5 #include "traits.hpp"
6 
7 namespace aaa {
8 
44 // iterators
46 
47 template<typename InputIterator1, typename InputIterator2, typename OutputIterator,
48  check_ratio<value_type_i<InputIterator1>, value_type_i<InputIterator2>, value_type_i<OutputIterator>> = nullptr>
49 void divide(InputIterator1 first_left, InputIterator1 last_left, InputIterator2 first_right, OutputIterator first_out)
50 {
51  auto f = [](const value_type_i<InputIterator1>& left, const value_type_i<InputIterator2>& right)
52  {
53  return left / right;
54  };
55  std::transform(first_left, last_left, first_right, first_out, f);
56 }
57 
58 template<typename Element, typename InputIterator, typename OutputIterator,
59  check_ratio<Element, value_type_i<InputIterator>, value_type_i<OutputIterator>> = nullptr>
60 void divide(const Element& left, InputIterator first_right, InputIterator last_right, OutputIterator first_out)
61 {
62  auto f = [&](const value_type_i<InputIterator>& right) { return left / right; };
63  std::transform(first_right, last_right, first_out, f);
64 }
65 
66 template<typename InputIterator, typename Element, typename OutputIterator,
67  check_ratio<value_type_i<InputIterator>, Element, value_type_i<OutputIterator>> = nullptr>
68 void divide(InputIterator first_left, InputIterator last_left, const Element& right, OutputIterator first_out)
69 {
70  auto f = [&](const value_type_i<InputIterator>& left) { return left / right; };
71  std::transform(first_left, last_left, first_out, f);
72 }
73 
75 // containers
76 
77 template<typename Container1, typename Container2, typename Container3,
78  check_ratio<value_type<Container1>, value_type<Container2>, value_type<Container3>> = nullptr>
79 void divide(const Container1& left, const Container2& right, Container3& out)
80 {
81  assert(left.size() == out.size());
82  assert(right.size() == out.size());
83  using std::begin;
84  using std::end;
85  divide(begin(left), end(left), begin(right), begin(out));
86 }
87 
88 template<typename Element, typename Container1, typename Container2,
89  check_ratio<Element, value_type<Container1>, value_type<Container2>> = nullptr>
90 void divide(const Element& left, const Container1& right, Container2& out)
91 {
92  assert(right.size() == out.size());
93  using std::begin;
94  using std::end;
95  divide(left, begin(right), end(right), begin(out));
96 }
97 
98 template<typename Container1, typename Element, typename Container2,
99  check_ratio<value_type<Container1>, Element, value_type<Container2>> = nullptr>
100 void divide(const Container1& left, const Element& right, Container2& out)
101 {
102  assert(left.size() == out.size());
103  using std::begin;
104  using std::end;
105  divide(begin(left), end(left), right, begin(out));
106 }
107 
109 // make containers
110 
111 template<typename Container>
112 Container divide(const Container& left, const Container& right)
113 {
114  auto out = left;
115  divide(left, right, out);
116  return out;
117 }
118 
119 template<typename Container>
120 Container divide(const Container& left, const value_type<Container>& right)
121 {
122  auto out = left;
123  divide(left, right, out);
124  return out;
125 }
126 
127 template<typename Container>
128 Container divide(const value_type<Container>& left, const Container& right)
129 {
130  auto out = right;
131  divide(left, right, out);
132  return out;
133 }
134 
137 } // namespace aaa
Definition: add.hpp:7