Auto-clear the bitfield on initialization
[alure.git] / src / main.h
blobcac45e6436be276fa9b8d59873d273b7b7dca44c
1 #ifndef ALURE_MAIN_H
2 #define ALURE_MAIN_H
4 #include "alure2.h"
6 #if __cplusplus >= 201703L
7 #include <variant>
8 #else
9 #include "mpark/variant.hpp"
10 #endif
11 #include <system_error>
14 #if !(__cplusplus >= 201703L)
15 namespace std {
16 using mpark::variant;
17 using mpark::monostate;
18 using mpark::get;
19 using mpark::get_if;
20 using mpark::holds_alternative;
21 } // namespace std
22 #endif
24 #ifdef __GNUC__
25 #define LIKELY(x) __builtin_expect(static_cast<bool>(x), true)
26 #define UNLIKELY(x) __builtin_expect(static_cast<bool>(x), false)
27 #else
28 #define LIKELY(x) static_cast<bool>(x)
29 #define UNLIKELY(x) static_cast<bool>(x)
30 #endif
32 #define DECL_THUNK0(ret, C, Name, cv) \
33 ret C::Name() cv { return pImpl->Name(); }
34 #define DECL_THUNK1(ret, C, Name, cv, T1) \
35 ret C::Name(T1 a) cv { return pImpl->Name(std::forward<T1>(a)); }
36 #define DECL_THUNK2(ret, C, Name, cv, T1, T2) \
37 ret C::Name(T1 a, T2 b) cv \
38 { return pImpl->Name(std::forward<T1>(a), std::forward<T2>(b)); }
39 #define DECL_THUNK3(ret, C, Name, cv, T1, T2, T3) \
40 ret C::Name(T1 a, T2 b, T3 c) cv \
41 { \
42 return pImpl->Name(std::forward<T1>(a), std::forward<T2>(b), \
43 std::forward<T3>(c)); \
47 namespace alure {
49 // Need to use these to avoid extraneous commas in macro parameter lists
50 using Vector3Pair = std::pair<Vector3,Vector3>;
51 using UInt64NSecPair = std::pair<uint64_t,std::chrono::nanoseconds>;
52 using SecondsPair = std::pair<Seconds,Seconds>;
53 using ALfloatPair = std::pair<ALfloat,ALfloat>;
54 using ALuintPair = std::pair<ALuint,ALuint>;
55 using BoolTriple = std::tuple<bool,bool,bool>;
58 template<typename T>
59 inline std::future_status GetFutureState(const SharedFuture<T> &future)
60 { return future.wait_for(std::chrono::seconds::zero()); }
62 // This variant is a poor man's optional
63 std::variant<std::monostate,uint64_t> ParseTimeval(StringView strval, double srate) noexcept;
65 template<size_t N>
66 struct Bitfield {
67 private:
68 Array<uint8_t,(N+7)/8> mElems;
70 public:
71 Bitfield() { std::fill(mElems.begin(), mElems.end(), 0); }
73 bool operator[](size_t i) const noexcept
74 { return static_cast<bool>(mElems[i/8] & (1<<(i%8))); }
76 void set(size_t i) noexcept { mElems[i/8] |= 1<<(i%8); }
80 class alc_category : public std::error_category {
81 alc_category() noexcept { }
83 public:
84 static alc_category sSingleton;
86 const char *name() const noexcept override final { return "alc_category"; }
87 std::error_condition default_error_condition(int code) const noexcept override final
88 { return std::error_condition(code, *this); }
90 bool equivalent(int code, const std::error_condition &condition) const noexcept override final
91 { return default_error_condition(code) == condition; }
92 bool equivalent(const std::error_code &code, int condition) const noexcept override final
93 { return *this == code.category() && code.value() == condition; }
95 std::string message(int condition) const override final;
97 template<typename T>
98 inline std::system_error alc_error(int code, T&& what)
99 { return std::system_error(code, alc_category::sSingleton, std::forward<T>(what)); }
100 inline std::system_error alc_error(int code)
101 { return std::system_error(code, alc_category::sSingleton); }
103 class al_category : public std::error_category {
104 al_category() noexcept { }
106 public:
107 static al_category sSingleton;
109 const char *name() const noexcept override final { return "al_category"; }
110 std::error_condition default_error_condition(int code) const noexcept override final
111 { return std::error_condition(code, *this); }
113 bool equivalent(int code, const std::error_condition &condition) const noexcept override final
114 { return default_error_condition(code) == condition; }
115 bool equivalent(const std::error_code &code, int condition) const noexcept override final
116 { return *this == code.category() && code.value() == condition; }
118 std::string message(int condition) const override final;
120 template<typename T>
121 inline std::system_error al_error(int code, T&& what)
122 { return std::system_error(code, al_category::sSingleton, std::forward<T>(what)); }
123 inline std::system_error al_error(int code)
124 { return std::system_error(code, al_category::sSingleton); }
126 inline void throw_al_error(const char *str)
128 ALenum err = alGetError();
129 if(UNLIKELY(err != AL_NO_ERROR))
130 throw al_error(err, str);
133 } // namespace alure
135 #endif /* ALURE_MAIN_H */