Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
arrays.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Utilities to apply template functors on index ranges.
15// See tests for examples.
16#ifndef OR_TOOLS_MATH_OPT_ELEMENTAL_ARRAYS_H_
17#define OR_TOOLS_MATH_OPT_ELEMENTAL_ARRAYS_H_
18
19#include <tuple>
20#include <utility>
21
23
24// Calls `fn<0, ..., n-1>()`, and returns the result. Typically used for
25// simple reduce operations that can be expressed as a fold.
26//
27// Examples:
28// - Sum of elements from 0 to 5 (result is 15):
29// `ApplyOnIndexRange<6>([]<int... i>() { return (i + ... + 0); });`
30//
31// - Sum of elements of array `a`:
32// ```
33// ApplyOnIndexRange<a.size()>([&a]<int... i>() {
34// return (a[i] + ... + 0);
35// });
36// ```
37template <int n, typename Fn>
38constexpr decltype(auto) ApplyOnIndexRange(Fn&& fn) {
39 // NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat)
40 return [&fn]<int... is>(std::integer_sequence<int, is...>) mutable {
41 return fn.template operator()<is...>();
42 }(std::make_integer_sequence<int, n>());
43}
44
45// Calls (fn<0>(), ..., fn<n-1>()).
46// Typically used for independent operations on elements, or more complex reduce
47// operations that cannot be expressed with a fold.
48//
49// Example (independent operations): Log each array element for some array `a`:
50// `ForEachIndex<a.size()>([&a]<int i>() { LOG(ERROR) << a[i]; });`
51//
52// NOTE: this returns the result of the last call, which allows returning some
53// internal state (and avoids capturing an external variable by reference) for
54// complex fold operations. See `CollectTest` for an example.
55template <int n, typename Fn>
56constexpr decltype(auto) ForEachIndex(Fn&& fn) {
58 // NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat)
59 [&fn]<int... is>() { return (fn.template operator()<is>(), ...); });
60}
61
62// Calls `fn` of each element of `tuple`, and returns the result of the
63// last invocation.
64template <typename Fn, typename Tuple>
65constexpr decltype(auto) ForEach(Fn&& fn, Tuple&& tuple) {
66 // NOLINTNEXTLINE(clang-diagnostic-pre-c++20-compat)
67 return std::apply([&fn]<typename... Ts>(
68 Ts&&... ts) { return (fn(std::forward<Ts>(ts)), ...); },
69 std::forward<Tuple>(tuple));
70}
71
72} // namespace operations_research::math_opt
73
74#endif // OR_TOOLS_MATH_OPT_ELEMENTAL_ARRAYS_H_
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
constexpr decltype(auto) ApplyOnIndexRange(Fn &&fn)
Definition arrays.h:38
constexpr decltype(auto) ForEachIndex(Fn &&fn)
Definition arrays.h:56
constexpr decltype(auto) ForEach(Fn &&fn, Tuple &&tuple)
Definition arrays.h:65