g2o
Loading...
Searching...
No Matches
integer_sequence_algorithm.h
Go to the documentation of this file.
1// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2018 Google Inc. All rights reserved.
3// http://ceres-solver.org/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: jodebo_beck@gmx.de (Johannes Beck)
30//
31// Algorithms to be used together with integer_sequence, like computing the sum
32// or the exclusive scan (sometimes called exclusive prefix sum) at compile
33// time.
34
35#ifndef G2O_CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
36#define G2O_CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
37
38#include <utility>
39
40namespace g2o {
41namespace ceres {
42namespace internal {
43
44// Implementation of calculating the sum of an integer sequence.
45// Recursively instantiate SumImpl and calculate the sum of the N first
46// numbers. This reduces the number of instantiations and speeds up
47// compilation.
48//
49// Examples:
50// 1) integer_sequence<int, 5>:
51// Value = 5
52//
53// 2) integer_sequence<int, 4, 2>:
54// Value = 4 + 2 + SumImpl<integer_sequence<int>>::Value
55// Value = 4 + 2 + 0
56//
57// 3) integer_sequence<int, 2, 1, 4>:
58// Value = 2 + 1 + SumImpl<integer_sequence<int, 4>>::Value
59// Value = 2 + 1 + 4
60template <typename Seq>
61struct SumImpl;
62
63// Strip of and sum the first number.
64template <typename T, T N, T... Ns>
65struct SumImpl<std::integer_sequence<T, N, Ns...>> {
66 static constexpr T Value =
67 N + SumImpl<std::integer_sequence<T, Ns...>>::Value;
68};
69
70// Strip of and sum the first two numbers.
71template <typename T, T N1, T N2, T... Ns>
72struct SumImpl<std::integer_sequence<T, N1, N2, Ns...>> {
73 static constexpr T Value =
74 N1 + N2 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
75};
76
77// Strip of and sum the first four numbers.
78template <typename T, T N1, T N2, T N3, T N4, T... Ns>
79struct SumImpl<std::integer_sequence<T, N1, N2, N3, N4, Ns...>> {
80 static constexpr T Value =
81 N1 + N2 + N3 + N4 + SumImpl<std::integer_sequence<T, Ns...>>::Value;
82};
83
84// Only one number is left. 'Value' is just that number ('recursion' ends).
85template <typename T, T N>
86struct SumImpl<std::integer_sequence<T, N>> {
87 static constexpr T Value = N;
88};
89
90// No number is left. 'Value' is the identity element (for sum this is zero).
91template <typename T>
92struct SumImpl<std::integer_sequence<T>> {
93 static constexpr T Value = T(0);
94};
95
96// Calculate the sum of an integer sequence. The resulting sum will be stored in
97// 'Value'.
98template <typename Seq>
99class Sum {
100 using T = typename Seq::value_type;
101
102 public:
103 static constexpr T Value = SumImpl<Seq>::Value;
104};
105
106// Implementation of calculating an exclusive scan (exclusive prefix sum) of an
107// integer sequence. Exclusive means that the i-th input element is not included
108// in the i-th sum. Calculating the exclusive scan for an input array I results
109// in the following output R:
110//
111// R[0] = 0
112// R[1] = I[0];
113// R[2] = I[0] + I[1];
114// R[3] = I[0] + I[1] + I[2];
115// ...
116//
117// In C++17 std::exclusive_scan does the same operation at runtime (but
118// cannot be used to calculate the prefix sum at compile time). See
119// https://en.cppreference.com/w/cpp/algorithm/exclusive_scan for a more
120// detailed description.
121//
122// Example for integer_sequence<int, 1, 4, 3> (seq := integer_sequence):
123// T , Sum, Ns... , Rs...
124// ExclusiveScanImpl<int, 0, seq<int, 1, 4, 3>, seq<int >>
125// ExclusiveScanImpl<int, 1, seq<int, 4, 3>, seq<int, 0 >>
126// ExclusiveScanImpl<int, 5, seq<int, 3>, seq<int, 0, 1 >>
127// ExclusiveScanImpl<int, 8, seq<int >, seq<int, 0, 1, 5>>
128// ^^^^^^^^^^^^^^^^^
129// resulting sequence
130template <typename T, T Sum, typename SeqIn, typename SeqOut>
132
133template <typename T, T Sum, T N, T... Ns, T... Rs>
134struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T, N, Ns...>,
135 std::integer_sequence<T, Rs...>> {
136 using Type =
137 typename ExclusiveScanImpl<T, Sum + N, std::integer_sequence<T, Ns...>,
138 std::integer_sequence<T, Rs..., Sum>>::Type;
139};
140
141// End of 'recursion'. The resulting type is SeqOut.
142template <typename T, T Sum, typename SeqOut>
143struct ExclusiveScanImpl<T, Sum, std::integer_sequence<T>, SeqOut> {
144 using Type = SeqOut;
145};
146
147// Calculates the exclusive scan of the specified integer sequence. The last
148// element (the total) is not included in the resulting sequence so they have
149// same length. This means the exclusive scan of integer_sequence<int, 1, 2, 3>
150// will be integer_sequence<int, 0, 1, 3>.
151template <typename Seq>
153 using T = typename Seq::value_type;
154
155 public:
156 using Type =
157 typename ExclusiveScanImpl<T, T(0), Seq, std::integer_sequence<T>>::Type;
158};
159
160// Helper to use exclusive scan without typename.
161template <typename Seq>
163
164} // namespace internal
165} // namespace ceres
166} // namespace g2o
167
168#endif // G2O_CERES_PUBLIC_INTERNAL_INTEGER_SEQUENCE_ALGORITHM_H_
typename ExclusiveScanImpl< T, T(0), Seq, std::integer_sequence< T > >::Type Type
typename ExclusiveScanT< Seq >::Type ExclusiveScan
Definition jet.h:876
typename ExclusiveScanImpl< T, Sum+N, std::integer_sequence< T, Ns... >, std::integer_sequence< T, Rs..., Sum > >::Type Type