forked from KhronosGroup/OpenXR-SDK-Source
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.h
99 lines (79 loc) · 3.21 KB
/
common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright (c) 2017-2023, The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <string>
#include <locale>
#include <algorithm>
#include <stdarg.h>
#include <stddef.h>
#include <openxr/openxr_reflection.h>
// Macro to generate stringify functions for OpenXR enumerations based data provided in openxr_reflection.h
// clang-format off
#define ENUM_CASE_STR(name, val) case name: return #name;
#define MAKE_TO_STRING_FUNC(enumType) \
inline const char* to_string(enumType e) { \
switch (e) { \
XR_LIST_ENUM_##enumType(ENUM_CASE_STR) \
default: return "Unknown " #enumType; \
} \
}
// clang-format on
MAKE_TO_STRING_FUNC(XrReferenceSpaceType);
MAKE_TO_STRING_FUNC(XrViewConfigurationType);
MAKE_TO_STRING_FUNC(XrEnvironmentBlendMode);
MAKE_TO_STRING_FUNC(XrSessionState);
MAKE_TO_STRING_FUNC(XrResult);
MAKE_TO_STRING_FUNC(XrFormFactor);
inline bool EqualsIgnoreCase(const std::string& s1, const std::string& s2, const std::locale& loc = std::locale()) {
const std::ctype<char>& ctype = std::use_facet<std::ctype<char>>(loc);
const auto compareCharLower = [&](char c1, char c2) { return ctype.tolower(c1) == ctype.tolower(c2); };
return s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), s2.begin(), compareCharLower);
}
struct IgnoreCaseStringLess {
bool operator()(const std::string& a, const std::string& b, const std::locale& loc = std::locale()) const noexcept {
const std::ctype<char>& ctype = std::use_facet<std::ctype<char>>(loc);
const auto ignoreCaseCharLess = [&](char c1, char c2) { return ctype.tolower(c1) < ctype.tolower(c2); };
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), ignoreCaseCharLess);
}
};
template <typename T>
struct ScopeGuard {
// Needs C++17: static_assert(std::is_invocable_v<T>, "Type must be invocable function.");
ScopeGuard(T&& guard) noexcept : m_guard(std::move(guard)) {}
ScopeGuard(ScopeGuard&&) noexcept = default;
ScopeGuard& operator=(ScopeGuard&&) noexcept = default;
ScopeGuard(ScopeGuard&) = delete;
ScopeGuard& operator=(ScopeGuard&) = delete;
~ScopeGuard() { m_guard(); }
private:
T m_guard;
};
// Usage: auto guard = MakeScopeGuard([&] { foobar; });
template <typename T>
ScopeGuard<T> MakeScopeGuard(T&& guard) {
return ScopeGuard<T>(std::forward<T>(guard));
}
inline std::string Fmt(const char* fmt, ...) {
va_list vl;
va_start(vl, fmt);
int size = std::vsnprintf(nullptr, 0, fmt, vl);
va_end(vl);
if (size != -1) {
std::unique_ptr<char[]> buffer(new char[size + 1]);
va_start(vl, fmt);
size = std::vsnprintf(buffer.get(), size + 1, fmt, vl);
va_end(vl);
if (size != -1) {
return std::string(buffer.get(), size);
}
}
throw std::runtime_error("Unexpected vsnprintf failure");
}
// The equivalent of C++17 std::size. A helper to get the dimension for an array.
template <typename T, size_t Size>
constexpr size_t ArraySize(const T (&/*unused*/)[Size]) noexcept {
return Size;
}
#include "logger.h"
#include "check.h"