std::inclusive_scan(3)
β¨ std::inclusive_scan β¨
okay bestie, so this is from the C++ Standard Library and it's literally about doing a running total but make it fashion π
π NAME π
std::inclusive_scan β bestie it's std::inclusive_scan, that's the whole name, periodt
π¦ Synopsis π¦
sooo this lives in the header <numeric> and there are six whole overloads, like she's an overachiever fr fr π
template< class InputIt, class OutputIt >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first );
(1) β since C++17, constexpr since C++20
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2 >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
(2) β since C++17
template< class InputIt, class OutputIt, class BinaryOp >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first, BinaryOp op );
(3) β since C++17, constexpr since C++20
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class BinaryOp >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryOp op );
(4) β since C++17
template< class InputIt, class OutputIt,
class BinaryOp, class T >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first, BinaryOp op, T init );
(5) β since C++17, constexpr since C++20
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2,
class BinaryOp, class T >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryOp op, T init );
(6) β since C++17
πΈ Description πΈ
okay so let me break this down for you bestie π«Ά
Overload (1) is literally equivalent to inclusive_scan(first, last, d_first, std::plus<>().
Overload (3) computes the inclusive prefix sum using op. no cap, that's the whole vibe.
For each integer i in [0, std::distance(first, last)), it performs these operations in order:
- Creates a sequence which is formed by the elements of
[first, iter]in order, whereiteris the next *i*th iterator offirst. - Computes the generalized noncommutative sum of the sequence over
op. - Assigns the result to
*dest, wheredestis the next *i*th iterator ofd_first.
Overload (5) is same as (3), but each sequence created is formed by init followed by the elements of [first, iter] in order. she adds an init, she's extra like that π
Overloads (2), (4), (6) are same as (1), (3), (5), but executed according to policy. iconic behavior honestly β¨
These overloads participate in overload resolution only if:
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>is true. β (until C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>is true. β (since C++20)
π§ the generalized noncommutative sum tea π§
The generalized, noncommutative sum of a sequence of elements over a binary operation binary_op is defined as follows:
- If the sequence only has one element, the sum is the value of the element. simple as that bestie π
- Otherwise, performs the following operations in order:
- Selects any two adjacent elements
elem1andelem2from the sequence. - Calculates
binary_op(elem1, elem2)and replaces the two elements in the sequence with the result. - Repeats steps 1 and 2 until there is only one element in the sequence.
- Selects any two adjacent elements
π the warning section (pay attention bestie) π
Given binary_op as the actual binary operation:
- The result is non-deterministic if the
binary_opis not associative (such as floating-point addition). π so like, don't come for her when the answer is different every time - For overloads (1-4), if
binary_op(*first, *first)is not convertible to the value type ofdecltype(first), the program is ill-formed. - For overloads (5,6), if any of the following values is not convertible to
T, the program is ill-formed:binary_op(init, *first)binary_op(init, init)binary_op(*first, *first)
- If any of the following conditions is satisfied, the behavior is undefined β like, actual chaos, not the fun kind π:
- For overloads (1-4), the value type of
decltype(first)is not MoveConstructible. - For overloads (5,6),
Tis not MoveConstructible. binary_opmodifies any element of[first, last).binary_opinvalidates any iterator or subrange of[first, last).
- For overloads (1-4), the value type of
β¨ Parameters β¨
first,lastβ the range of elements to sum πd_firstβ the beginning of the destination range; may be equal tofirst(she can multitask, we stan)policyβ the execution policy to use. See execution policy for details. πinitβ the initial value πopβ binary FunctionObject that will be applied in to the result of dereferencing the input iterators, the results of otherop, andinit(if provided) π¦
π₯ Type requirements π₯
InputItmust meet the requirements of LegacyInputIterator.OutputItmust meet the requirements of LegacyOutputIterator.ForwardIt1,ForwardIt2must meet the requirements of LegacyForwardIterator.
π Return value π
Iterator to the element past the last element written. she returns where she left off, organized queen π
π Complexity π
Given N (that's (\scriptsize N)N) as std::distance(first, last):
- (1,2) β (\scriptsize O(N))O(N) applications of
std::plus<>(). - (3-6) β (\scriptsize O(N))O(N) applications of
op.
π«Ά Exceptions π«Ά
The overloads with a template parameter named ExecutionPolicy report errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicyis one of the standard policies,std::terminateis called. For any otherExecutionPolicy, the behavior is implementation-defined. π¬ - If the algorithm fails to allocate memory,
std::bad_allocis thrown. rude but okay π
π Example π
run this code bestie, it's giving main character energy β¨
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
int main()
{
std::vector data{3, 1, 4, 1, 5, 9, 2, 6};
std::cout << "Exclusive sum: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
0);
std::cout << "\nInclusive sum: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n\nExclusive product: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
1, std::multiplies<>{});
std::cout << "\nInclusive product: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
std::multiplies<>{});
}
π Output π
Exclusive sum: 0 3 4 8 9 14 23 25
Inclusive sum: 3 4 8 9 14 23 25 31
Exclusive product: 1 3 3 12 12 60 540 1080
Inclusive product: 3 3 12 12 60 540 1080 6480
π§ See also π§
adjacent_differenceβ computes the differences between adjacent elements in a range (function template)accumulateβ sums up or folds a range of elements (function template)partial_sumβ computes the partial sum of a range of elements (function template)transform_inclusive_scan(C++17) β applies an invocable, then calculates inclusive scan (function template)exclusive_scan(C++17) β similar tostd::partial_sum, excludes the *i*th input element from the *i*th sum (function template)
okay that's the whole page bestie, you're officially an inclusive_scan expert now, go slay π β¨π
source: http://cppreference.com β version 2024.06.10 β page std::inclusive_scan(3) π mwah, love u, bye π«Άπ
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms