17 #ifdef XRTRAITS_USE_EXCEPTIONS 131 #ifndef XRTRAITS_DOXYGEN 134 static constexpr uint32_t MAX_CALLS_FOR_TWO_CALL_IDIOM = 5;
137 bool doneCalling =
false;
138 XrResult returnCode = XR_SUCCESS;
142 template <
typename F,
typename... Args>
143 static inline TwoCallResult getCount(F&& wrappedCall, Args&&... a)
146 ret.returnCode = wrappedCall(std::forward<Args>(a)..., 0,
147 &ret.count,
nullptr);
149 if (ret.returnCode != XR_SUCCESS) {
152 ret.doneCalling =
true;
153 }
else if (ret.count == 0) {
155 ret.doneCalling =
true;
160 template <
typename T,
typename F,
typename... Args>
161 static inline TwoCallResult callOnce(std::vector<T>& container,
162 F&& wrappedCall, Args&&... a)
167 if (container.empty()) {
169 ret = getCount(std::forward<F>(wrappedCall),
170 std::forward<Args>(a)...);
174 wrappedCall(std::forward<Args>(a)...,
175 uint32_t(container.size()), &ret.count,
181 ret.returnCode != XR_ERROR_SIZE_INSUFFICIENT;
184 if (ret.returnCode == XR_SUCCESS ||
185 ret.returnCode == XR_ERROR_SIZE_INSUFFICIENT) {
186 container.resize(ret.count, make_zeroed<T>());
192 template <
typename T,
typename F,
typename... Args>
193 static inline XrResult twoCallLoop(uint32_t max_calls,
194 std::vector<T>& container,
195 F&& wrappedCall, Args&&... a)
197 TwoCallResult result;
200 for (uint32_t i = 0; !result.doneCalling && i < max_calls;
203 callOnce(container, std::forward<F>(wrappedCall),
204 std::forward<Args>(a)...);
206 return result.returnCode;
210 #endif // !XRTRAITS_DOXYGEN 212 #ifdef XRTRAITS_USE_EXCEPTIONS 228 template <
typename T,
typename F,
typename... Args>
229 inline std::vector<T>
doTwoCall(F&& wrappedCall, Args&&... a)
232 auto countResults = detail::getCount(std::forward<F>(wrappedCall),
233 std::forward<Args>(a)...);
236 countResults.returnCode,
"Failed getting count in two-call idiom");
238 std::vector<T> container = make_zeroed_vector<T>(countResults.count);
239 if (!container.empty()) {
240 XrResult result = detail::twoCallLoop(
241 detail::MAX_CALLS_FOR_TWO_CALL_IDIOM, container,
242 std::forward<F>(wrappedCall), std::forward<Args>(a)...);
244 result,
"Failed in retrieving two-call values");
268 template <
typename T,
typename F,
typename... Args>
273 std::vector<T> container = make_zeroed_vector<T>(sizeHint);
274 XrResult result = detail::twoCallLoop(
275 detail::MAX_CALLS_FOR_TWO_CALL_IDIOM, container,
276 std::forward<F>(wrappedCall), std::forward<Args>(a)...);
278 result,
"Failed in retrieving two-call values");
281 #endif // XRTRAITS_USE_EXCEPTIONS 299 template <
typename T,
typename F,
typename... Args>
304 return detail::twoCallLoop(detail::MAX_CALLS_FOR_TWO_CALL_IDIOM,
305 container, std::forward<F>(wrappedCall),
306 std::forward<Args>(a)...);
Main namespace for these C++ OpenXR utilities.
Definition: GetChained.h:26
std::vector< T > doTwoCallWithSizeHint(uint32_t sizeHint, F &&wrappedCall, Args &&... a)
Definition: TwoCall.h:269
Header providing a variety of ways to create or initialize an OpenXR "tagged struct".
void throwIfNotUnqualifiedSuccess(XrResult result, const char *errorMessage)
std::vector< T > doTwoCall(F &&wrappedCall, Args &&... a)
Definition: TwoCall.h:229
XrResult doTwoCallInPlace(std::vector< T > &container, F &&wrappedCall, Args &&... a)
Definition: TwoCall.h:300
std::vector< T > make_zeroed_vector(size_t n)
Definition: InitXrType.h:114