Browse Source

GL: add a type trait for checking if a type is an extension.

Similar to what Vulkan has. Will be used mainly for guarding implicit
conversion to the Extension class.
euler-xxx
Vladimír Vondruš 5 years ago
parent
commit
49630d43d4
  1. 29
      src/Magnum/GL/Context.h
  2. 45
      src/Magnum/GL/Test/ContextTest.cpp

29
src/Magnum/GL/Context.h

@ -57,6 +57,14 @@ namespace GL {
namespace Implementation {
struct ContextState;
struct State;
template<class...> class IsExtension;
template<> class IsExtension<> { public: enum: bool { value = true }; };
CORRADE_HAS_TYPE(IsExtension<U>, decltype(T::Index));
template<class T, class U, class ...Args> class IsExtension<T, U, Args...> {
/** @todo C++17: use &&... instead of all this */
public: enum: bool { value = IsExtension<T>::value && IsExtension<U, Args...>::value };
};
}
/**
@ -650,8 +658,8 @@ class MAGNUM_GL_EXPORT Context {
* @ref MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(),
* @ref isExtensionDisabled()
*/
template<class T> bool isExtensionSupported() const {
return isExtensionSupported<T>(version());
template<class E> bool isExtensionSupported() const {
return isExtensionSupported<E>(version());
}
/**
@ -664,8 +672,9 @@ class MAGNUM_GL_EXPORT Context {
*
* @snippet MagnumGL.cpp Context-isExtensionSupported-version
*/
template<class T> bool isExtensionSupported(Version version) const {
return _extensionRequiredVersion[T::Index] <= version && _extensionStatus[T::Index];
template<class E> bool isExtensionSupported(Version version) const {
static_assert(Implementation::IsExtension<E>::value, "expected an OpenGL extension");
return _extensionRequiredVersion[E::Index] <= version && _extensionStatus[E::Index];
}
/**
@ -688,8 +697,8 @@ class MAGNUM_GL_EXPORT Context {
* extensions return `false` in @ref isExtensionSupported() even if
* they are advertised as being supported by the driver.
*/
template<class T> bool isExtensionDisabled() const {
return isExtensionDisabled<T>(version());
template<class E> bool isExtensionDisabled() const {
return isExtensionDisabled<E>(version());
}
/**
@ -698,9 +707,11 @@ class MAGNUM_GL_EXPORT Context {
* Similar to above, but can also check for extensions which are
* disabled only for particular versions.
*/
template<class T> bool isExtensionDisabled(Version version) const {
/* The extension is advertised, but the minimal version has been increased */
return T::requiredVersion() <= version && _extensionRequiredVersion[T::Index] > version;
template<class E> bool isExtensionDisabled(Version version) const {
static_assert(Implementation::IsExtension<E>::value, "expected an OpenGL extension");
/* The extension is advertised, but the minimal version has been
increased */
return E::requiredVersion() <= version && _extensionRequiredVersion[E::Index] > version;
}
/**

45
src/Magnum/GL/Test/ContextTest.cpp

@ -37,6 +37,8 @@ namespace Magnum { namespace GL { namespace Test { namespace {
struct ContextTest: TestSuite::Tester {
explicit ContextTest();
void isExtension();
void constructNoCreate();
void constructCopyMove();
@ -52,7 +54,9 @@ struct ContextTest: TestSuite::Tester {
};
ContextTest::ContextTest() {
addTests({&ContextTest::constructNoCreate,
addTests({&ContextTest::isExtension,
&ContextTest::constructNoCreate,
&ContextTest::constructCopyMove,
&ContextTest::makeCurrentNoOp,
@ -66,6 +70,45 @@ ContextTest::ContextTest() {
&ContextTest::debugDetectedDrivers});
}
void ContextTest::isExtension() {
CORRADE_VERIFY(Implementation::IsExtension<Extensions::KHR::debug>::value);
CORRADE_VERIFY(!Implementation::IsExtension<Extension>::value);
CORRADE_VERIFY(!Implementation::IsExtension<int>::value);
{
/* Not really a problem right now, but once people hit this we might
want to guard against this (especially because the Index might be
out of bounds) */
struct ALExtension {
enum: std::size_t { Index };
};
CORRADE_EXPECT_FAIL("AL/Vk extensions are not rejected right now.");
CORRADE_VERIFY(!Implementation::IsExtension<ALExtension>::value);
}
/* Variadic check (used in variadic addEnabledExtensions()), check that it
properly fails for each occurence of a non-extension */
CORRADE_VERIFY((Implementation::IsExtension<
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic,
Extensions::KHR::texture_compression_astc_hdr>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extension,
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extensions::KHR::debug,
Extension,
Extensions::EXT::texture_filter_anisotropic>::value));
CORRADE_VERIFY(!(Implementation::IsExtension<
Extensions::KHR::debug,
Extensions::EXT::texture_filter_anisotropic,
Extension>::value));
/* Empty variadic list should return true */
CORRADE_VERIFY(Implementation::IsExtension<>::value);
}
void ContextTest::constructNoCreate() {
{
/* Shouldn't crash during construction, shouldn't attempt to access GL,

Loading…
Cancel
Save