Blender V4.3
BLI_devirtualize_parameters.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
36namespace blender {
37
51template<typename Fn, typename... Devirtualizers>
52inline bool call_with_devirtualized_parameters(const std::tuple<Devirtualizers...> &devis,
53 const Fn &fn)
54{
55 /* In theory the code below could be generalized to avoid code duplication. However, the maximum
56 * number of parameters is expected to be relatively low. Explicitly implementing the different
57 * cases makes it more obvious to see what is going on and also makes inlining everything easier
58 * for the compiler. */
59 constexpr size_t DeviNum = sizeof...(Devirtualizers);
60 if constexpr (DeviNum == 0) {
61 fn();
62 return true;
63 }
64 if constexpr (DeviNum == 1) {
65 return std::get<0>(devis).devirtualize([&](auto param0) {
66 fn(param0);
67 return true;
68 });
69 }
70 if constexpr (DeviNum == 2) {
71 return std::get<0>(devis).devirtualize([&](auto &&param0) {
72 return std::get<1>(devis).devirtualize([&](auto &&param1) {
73 fn(param0, param1);
74 return true;
75 });
76 });
77 }
78 if constexpr (DeviNum == 3) {
79 return std::get<0>(devis).devirtualize([&](auto &&param0) {
80 return std::get<1>(devis).devirtualize([&](auto &&param1) {
81 return std::get<2>(devis).devirtualize([&](auto &&param2) {
82 fn(param0, param1, param2);
83 return true;
84 });
85 });
86 });
87 }
88 if constexpr (DeviNum == 4) {
89 return std::get<0>(devis).devirtualize([&](auto &&param0) {
90 return std::get<1>(devis).devirtualize([&](auto &&param1) {
91 return std::get<2>(devis).devirtualize([&](auto &&param2) {
92 return std::get<3>(devis).devirtualize([&](auto &&param3) {
93 fn(param0, param1, param2, param3);
94 return true;
95 });
96 });
97 });
98 });
99 }
100 if constexpr (DeviNum == 5) {
101 return std::get<0>(devis).devirtualize([&](auto &&param0) {
102 return std::get<1>(devis).devirtualize([&](auto &&param1) {
103 return std::get<2>(devis).devirtualize([&](auto &&param2) {
104 return std::get<3>(devis).devirtualize([&](auto &&param3) {
105 return std::get<4>(devis).devirtualize([&](auto &&param4) {
106 fn(param0, param1, param2, param3, param4);
107 return true;
108 });
109 });
110 });
111 });
112 });
113 }
114 if constexpr (DeviNum == 6) {
115 return std::get<0>(devis).devirtualize([&](auto &&param0) {
116 return std::get<1>(devis).devirtualize([&](auto &&param1) {
117 return std::get<2>(devis).devirtualize([&](auto &&param2) {
118 return std::get<3>(devis).devirtualize([&](auto &&param3) {
119 return std::get<4>(devis).devirtualize([&](auto &&param4) {
120 return std::get<5>(devis).devirtualize([&](auto &&param5) {
121 fn(param0, param1, param2, param3, param4, param5);
122 return true;
123 });
124 });
125 });
126 });
127 });
128 });
129 }
130 if constexpr (DeviNum == 7) {
131 return std::get<0>(devis).devirtualize([&](auto &&param0) {
132 return std::get<1>(devis).devirtualize([&](auto &&param1) {
133 return std::get<2>(devis).devirtualize([&](auto &&param2) {
134 return std::get<3>(devis).devirtualize([&](auto &&param3) {
135 return std::get<4>(devis).devirtualize([&](auto &&param4) {
136 return std::get<5>(devis).devirtualize([&](auto &&param5) {
137 return std::get<6>(devis).devirtualize([&](auto &&param6) {
138 fn(param0, param1, param2, param3, param4, param5, param6);
139 return true;
140 });
141 });
142 });
143 });
144 });
145 });
146 });
147 }
148 return false;
149}
150
157template<typename T> struct BasicDevirtualizer {
158 const T value;
159
160 template<typename Fn> bool devirtualize(const Fn &fn) const
161 {
162 return fn(this->value);
163 }
164};
165
166} // namespace blender
bool call_with_devirtualized_parameters(const std::tuple< Devirtualizers... > &devis, const Fn &fn)