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