VCCC  2024.05
VisualCamp Common C++ library
sum.hpp
Go to the documentation of this file.
1 # /*
2 # * Created by YongGyu Lee on 2020/12/08.
3 # */
4 #
5 # ifndef VCCC_NUMERIC_SUM_HPP
6 # define VCCC_NUMERIC_SUM_HPP
7 #
8 # include <numeric>
9 #
10 # include "vccc/type_traits.hpp"
11 
12 namespace vccc {
13 
22 namespace impl {
23 template<typename T>
24 constexpr inline T sumImpl(const T& arg){
25  return arg;
26 }
27 
28 template<typename Arg1, typename Arg2>
29 constexpr inline auto sumImpl(const Arg1& arg1, const Arg2& arg2) -> decltype(arg1 + arg2) {
30  return arg1 + arg2;
31 }
32 
33 template<typename Arg, typename ...Args>
34 constexpr auto sumImpl(const Arg& arg, const Args&... args) -> decltype(arg + sumImpl(args...)) {
35  return arg + sumImpl(args...);
36 }
37 
38 template<typename T, std::enable_if_t<std::is_class<std::decay_t<T>>::value, int> = 0>
39 constexpr inline std::decay_t<T> default_value() {
40  return std::decay_t<T>();
41 }
42 
43 template<typename T, std::enable_if_t<!std::is_class<std::decay_t<T>>::value, int> = 0>
44 constexpr inline std::decay_t<T> default_value() {
45  return static_cast<std::decay_t<T>>(0);
46 }
47 
48 } // namespace impl
49 
57 constexpr auto sum(InputIterator first, InputIterator last) {
58  auto s = impl::default_value<decltype(*first)>();
59  for (; first != last; ++first) {
60  s += *first;
61  }
62  return s;
63 }
64 
73 constexpr auto sum(InputIterator first, InputIterator last, UnaryOperation unary_op) {
74  auto s = impl::default_value<decltype(unary_op(*first))>();
75  for (; first != last; ++first) {
76  s += unary_op(*first);
77  }
78  return s;
79 }
80 
86 template<typename ...Args, std::enable_if_t<negation<disjunction<is_iterable<Args>...>>::value, int> = 0>
87 constexpr inline auto sum(const Args&... args) {
88  return impl::sumImpl(args...);
89 }
90 
98 template<typename UnaryOperation, typename Arg>
99 constexpr inline auto sum_custom(const UnaryOperation& unary_op, const Arg& arg) {
100  return unary_op(arg);
101 }
102 
103 template<typename UnaryOperation, typename Arg, typename ...Args>
104 constexpr inline auto sum_custom(const UnaryOperation& unary_op, const Arg& arg, const Args&... args) {
105  return unary_op(arg) + sum_custom(unary_op, args...);
106 }
108 
109 
115 template<typename T>
116 constexpr T square(const T& val) {
117  return val * val;
118 }
119 
120 
132 constexpr auto square_sum(InputIterator first, InputIterator last) {
133  return sum(first, last, [](const auto& val){ return square(val); });
134 }
135 
136 template<typename Arg>
137 constexpr auto square_sum(const Arg& arg) {
138  return square(arg);
139 }
140 
141 template<typename Arg1, typename Arg2,
142  std::enable_if_t<
143  negation<
144  disjunction<
145  is_iterator<Arg1>,
146  is_iterable<Arg2>
147  >
148  >::value, int> = 0>
149 constexpr auto square_sum(const Arg1& arg1, const Arg2& arg2) {
150  return square(arg1) + square(arg2);
151 }
152 
158 template<typename Arg, typename ...Args, std::enable_if_t<!is_iterable<Arg>::value, int> = 0>
159 constexpr auto square_sum(const Arg& arg, const Args&... args) {
160  return square(arg) + square_sum(args...);
161 }
163 
165 
166 } // namespace vccc
167 
168 # endif // VCCC_NUMERIC_SUM_HPP
constexpr auto square_sum(InputIterator first, InputIterator last)
square sum of iterator [first, last)
Definition: sum.hpp:132
constexpr auto sum(InputIterator first, InputIterator last)
sum of iterator [first, last)
Definition: sum.hpp:57
constexpr auto sum_custom(const UnaryOperation &unary_op, const Arg &arg)
sum of variadic with custom operator
Definition: sum.hpp:99
constexpr T square(const T &val)
get squared value
Definition: sum.hpp:116
constexpr T sumImpl(const T &arg)
Definition: sum.hpp:24
constexpr std::decay_t< T > default_value()
Definition: sum.hpp:39
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 0 > first
Definition: key_value.hpp:34
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35