tests/gltraits.cpp
27d69715
 #include <cstddef>
e38947dc
 #include <iomanip>
 #include <iostream>
 #include <string>
 #include <type_traits>
 
 #include <glm/glm.hpp>
 
 #include <glbase.hpp>
 #include <gltraits.hpp>
 
 
 struct GLTraitsTest : protected GLBase
 {
 
     template<typename Value>
     void static test_value()
     {
         using Traits = GLTraits::Value<Value>;
         static_assert(
             std::is_empty<Traits>::value,
             "GLTraits::Value must be empty"
         );
         #define GLTRAITS_TEST_VALUE(NAME, VALUE) \
             << std::left << std::setw(35) << "  " NAME ":" << VALUE << "\n"
         #define GLTRAITS_TEST_VALUE_DEC(NAME) \
             GLTRAITS_TEST_VALUE(#NAME, std::dec << Traits::NAME)
         #define GLTRAITS_TEST_VALUE_BOOL(NAME) \
             GLTRAITS_TEST_VALUE(#NAME, std::boolalpha << Traits::NAME)
a6304722
         #define GLTRAITS_TEST_VALUE_HEX(NAME) \
             GLTRAITS_TEST_VALUE(#NAME, str_enum_(Traits::NAME))
e38947dc
         #define GLTRAITS_TEST_VALUE_ENUM(NAME, SUFFIX) \
             GLTRAITS_TEST_VALUE( \
                 #NAME #SUFFIX, \
                 str_##NAME##_(Traits::NAME##SUFFIX) \
             )
         std::cout
             << "Value<" << Traits::name << ">" << "\n"
             GLTRAITS_TEST_VALUE_DEC(columns)
             GLTRAITS_TEST_VALUE_DEC(rows)
             GLTRAITS_TEST_VALUE_ENUM(glsl,)
             GLTRAITS_TEST_VALUE_ENUM(format,)
             GLTRAITS_TEST_VALUE_ENUM(type,)
             GLTRAITS_TEST_VALUE_ENUM(internal_format,)
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _srgb)
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed)
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed_srgb)
a6304722
             GLTRAITS_TEST_VALUE_BOOL(integer)
             GLTRAITS_TEST_VALUE_HEX(id);
     }
 
     template<GLenum id>
     void static test_value_id()
     {
         using Traits = GLTraits::ValueID<id>;
         static_assert(
             std::is_empty<Traits>::value,
             "GLTraits::ValueID must be empty"
         );
         std::cout
             << "ValueID<" << str_enum_(id) << ">" << "\n"
             << "  " << GLTraits::Value<typename Traits::Value>::name << "\n";
e38947dc
     }
 
799e1ae5
     template<GLenum object_type, typename... Args>
     void static test_object()
     {
         using Traits = GLTraits::Object<object_type>;
         static_assert(
             std::is_empty<Traits>::value,
             "GLTraits::Object must be empty"
         );
         #define GLTRAITS_TEST_OBJECT(NAME) \
             << std::left << std::setw(33) \
             << "  " #NAME ":" \
             << (void *)Traits::NAME \
             << "\n"
         std::cout
             << "Object<" << Traits::name << ">" << "\n"
             GLTRAITS_TEST_OBJECT(template gen_objects<Args...>)
             GLTRAITS_TEST_OBJECT(delete_objects)
             GLTRAITS_TEST_OBJECT(info_log);
     }
 
3378873e
     template<std::size_t N>
     void static test_texture()
     {
         using Traits = GLTraits::Texture<N>;
         static_assert(
             std::is_empty<Traits>::value,
             "GLTraits::Texture must be empty"
         );
         #define GLTRAITS_TEST_TEXTURE(NAME) \
             << std::left << std::setw(32) \
             << "  " #NAME ":" \
             << (void *)Traits::NAME \
             << "\n"
         std::cout
             << "Texture<" << N << ">" << "\n"
             GLTRAITS_TEST_TEXTURE(template tex_image<>)
             GLTRAITS_TEST_TEXTURE(template tex_storage<>)
             GLTRAITS_TEST_TEXTURE(template texture_storage<>)
             GLTRAITS_TEST_TEXTURE(template tex_sub_image<>)
             GLTRAITS_TEST_TEXTURE(template texture_sub_image<>)
             GLTRAITS_TEST_TEXTURE(copy_tex_sub_image)
             GLTRAITS_TEST_TEXTURE(copy_texture_sub_image)
             GLTRAITS_TEST_TEXTURE(compressed_tex_image)
             GLTRAITS_TEST_TEXTURE(compressed_tex_sub_image)
             GLTRAITS_TEST_TEXTURE(compressed_texture_sub_image);
     }
 
27d69715
     #if __cplusplus >= 201402L
     template<
5ee00b59
         typename    T,
27d69715
         typename    Value,
23a16d29
         std::size_t offset,
         typename... Members
27d69715
     >
     void static test_members(
23a16d29
         GLTraits::Members<T, GLTraits::Member<Value, offset>, Members...>
27d69715
     )
     {
23a16d29
         auto constexpr end = offset + sizeof(Value);
27d69715
         using Traits = GLTraits::Value<Value>;
         static_assert(
             std::is_empty<GLTraits::Members<
23a16d29
                 T, GLTraits::Member<Value, offset>, Members...
27d69715
             >>::value,
             "GLTraits::Members must be empty"
         );
23a16d29
         static_assert(
             std::is_empty<GLTraits::Member<Value, offset>>::value,
             "GLTraits::Member must be empty"
         );
27d69715
         #define GLTRAITS_TEST_MEMBERS(IND, NAME, OFFSET, END) \
             std::cout \
                 << std::left  << std::setw(IND)           << "" \
                 << std::left  << std::setw(12 - IND)      << NAME   << " " \
                 << std::right << std::setw(2) << std::dec << OFFSET << " " \
                 << std::right << std::setw(3) << std::dec << END    << "\n";
         GLTRAITS_TEST_MEMBERS(2, Traits::name, offset, end)
23a16d29
         test_members(GLTraits::Members<T, Members...>{});
27d69715
     }
5ee00b59
     template<typename T>
23a16d29
     void static test_members(GLTraits::Members<T>)
27d69715
     {}
     #endif
 
e38947dc
 };
 
 
 int main()
 {
     GLTraitsTest::test_value<GLfloat>();
     GLTraitsTest::test_value<bool>();
     GLTraitsTest::test_value<GLshort>();
     GLTraitsTest::test_value<GLdouble>();
     GLTraitsTest::test_value<glm::mat4x3>();
     GLTraitsTest::test_value<glm::uvec2>();
     GLTraitsTest::test_value<glm::dvec2>();
a6304722
 
     GLTraitsTest::test_value_id<GL_FLOAT>();
     GLTraitsTest::test_value_id<GL_BOOL>();
     GLTraitsTest::test_value_id<GL_SHORT>();
     GLTraitsTest::test_value_id<GL_DOUBLE>();
     GLTraitsTest::test_value_id<GL_FLOAT_MAT4x3>();
     GLTraitsTest::test_value_id<GL_UNSIGNED_INT_VEC2>();
     GLTraitsTest::test_value_id<GL_DOUBLE_VEC2>();
799e1ae5
 
     GLTraitsTest::test_object<GL_SHADER, GLenum>();
     GLTraitsTest::test_object<GL_PROGRAM_PIPELINE>();
3378873e
 
     GLTraitsTest::test_texture<1>();
     GLTraitsTest::test_texture<2>();
     GLTraitsTest::test_texture<3>();
27d69715
 
     #if __cplusplus >= 201402L
     struct Vertex
     {
         glm::vec3  position;
         glm::vec2  tex_coord;
         glm::mat3  tbn;
         glm::ivec4 bone_indices;
         glm::vec4  bone_weights;
         GLubyte    flags;
         GLdouble   unaligned;
     };
     #define GLTRAITS_TEST_MEMBERS_T(T) \
         GLTRAITS_TEST_MEMBERS(0, #T, 0, sizeof(T))
     #define GLTRAITS_TEST_MEMBERS_OFFSETOF(T, MEMBER) \
         GLTRAITS_TEST_MEMBERS( \
             2, \
             GLTraits::Value<decltype(T::MEMBER)>::name, \
             offsetof(T, MEMBER), \
             offsetof(T, MEMBER) + sizeof(T::MEMBER) \
         )
     GLTRAITS_TEST_MEMBERS_T(Vertex)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, position)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, tex_coord)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, tbn)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, bone_indices)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, bone_weights)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, flags)
     GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, unaligned)
     GLTRAITS_TEST_MEMBERS_T(Vertex)
     GLTraitsTest::test_members(GLTraits::members<Vertex>());
     #endif
e38947dc
 }