... | ... |
@@ -1,6 +1,6 @@ |
1 | 1 |
# [`gltraits`][] |
2 | 2 |
|
3 |
-A [C++11][]/[OpenGL][]>=[1.0][](/[GLM][]) [trait][]s library. |
|
3 |
+A [C++11][](/[C++14][])/[OpenGL][]>=[1.0][](/[GLM][]) [trait][]s library. |
|
4 | 4 |
|
5 | 5 |
This library seeks to unify some parts of the OpenGL [API][] to ease [generic |
6 | 6 |
programming][]. It also provides sensible default arguments, [optional][debug] |
... | ... |
@@ -46,6 +46,7 @@ further. |
46 | 46 |
|
47 | 47 |
[`gltraits`]: https://git.rcrnstn.net/rcrnstn/gltraits |
48 | 48 |
[C++11]: https://en.wikipedia.org/wiki/C++11 |
49 |
+[C++14]: https://en.wikipedia.org/wiki/C++14 |
|
49 | 50 |
[OpenGL]: https://en.wikipedia.org/wiki/OpenGL |
50 | 51 |
[1.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history |
51 | 52 |
[GLM]: https://glm.g-truc.net |
... | ... |
@@ -383,6 +384,92 @@ signatures for `glFramebufferTexture1D` and `glFramebufferTexture{2,3}D`.) |
383 | 384 |
[immutable storage]: https://www.khronos.org/opengl/wiki/Texture_Storage#Immutable_storage |
384 | 385 |
[pixel transfer parameters]: https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_transfer_parameters |
385 | 386 |
|
387 |
+### Member |
|
388 |
+ |
|
389 |
+`GLTraits::members()` provides compile time reflection for types consisting |
|
390 |
+(only) of types supported by `GLTraits::Value`. This feature is only available |
|
391 |
+if [C++14][] or above is supported. |
|
392 |
+ |
|
393 |
+If `T` is a non-[empty][] [trivially copyable][] [standard-layout][] type and |
|
394 |
+there exists template specializations of `GLTraits::Value` for the types of |
|
395 |
+either |
|
396 |
+ |
|
397 |
+- public member variables of `T`, if `T` is a [class][], or |
|
398 |
+- elements of `T`, if `T` is an [array][], or |
|
399 |
+- `T` itself, if `T` is a [scalar][] |
|
400 |
+ |
|
401 |
+then `constexpr auto GLTraits::members<T>()` returns an instance of the |
|
402 |
+[empty][] `struct GLTraits::Members<typename... Values>` where `Values...` are |
|
403 |
+the ("member") types above, in the order they occur in `T`. |
|
404 |
+ |
|
405 |
+An example use case would be along the lines of: |
|
406 |
+ |
|
407 |
+```cpp |
|
408 |
+template< |
|
409 |
+ typename Value, |
|
410 |
+ typename... Values |
|
411 |
+> |
|
412 |
+void vertex_setup( |
|
413 |
+ GLTraits::Members<Value, Values...>, |
|
414 |
+ std::size_t stride, |
|
415 |
+ std::size_t offset = 0, |
|
416 |
+ GLint location = 0 |
|
417 |
+) |
|
418 |
+{ |
|
419 |
+ auto unaligned = offset % alignof(Value); |
|
420 |
+ if (unaligned) |
|
421 |
+ offset += alignof(Value) - unaligned; |
|
422 |
+ GLTraits::Value<Value>::vertex_attrib_pointer(location, offset, stride); |
|
423 |
+ vertex_setup( |
|
424 |
+ GLTraits::Members<Values...>{}, |
|
425 |
+ stride, |
|
426 |
+ offset + sizeof(Value), |
|
427 |
+ location + GLTraits::Value<Value>::columns |
|
428 |
+ ); |
|
429 |
+} |
|
430 |
+void vertex_setup(GLTraits::Members<>, std::size_t, std::size_t, GLint) |
|
431 |
+{} |
|
432 |
+ |
|
433 |
+struct Vertex |
|
434 |
+{ |
|
435 |
+ glm::vec3 position; |
|
436 |
+ glm::vec2 tex_coord; |
|
437 |
+ glm::mat3 tbn; |
|
438 |
+ glm::ivec4 bone_indices; |
|
439 |
+ glm::vec4 bone_weights; |
|
440 |
+ GLubyte flags; |
|
441 |
+ GLdouble unaligned; |
|
442 |
+}; |
|
443 |
+vertex_setup(GLTraits::members<Vertex>(), sizeof(Vertex)); |
|
444 |
+``` |
|
445 |
+ |
|
446 |
+This use case is tested in [`tests/vertex_setup.cpp`][]. To verify that the |
|
447 |
+compiler sees through all the templates, a script that builds it and |
|
448 |
+disassembles it available in [`doc/vertex_setup`][] and its output in |
|
449 |
+[`doc/vertex_setup.i`][]. |
|
450 |
+ |
|
451 |
+It is recommended to use a library based on `gltraits` that abstracts this |
|
452 |
+further. |
|
453 |
+ |
|
454 |
+Many thanks to Antony Polukhin (the author of [Boost.PFR][] and its standalone |
|
455 |
+version [`magic_get`][]) on whose talks this implementation is based: |
|
456 |
+ |
|
457 |
+- [CppCon 2016: C++14 Reflections Without Macros, Markup nor External Tooling][] |
|
458 |
+- [Meeting C++ 2018: Better C++14 reflections][] |
|
459 |
+ |
|
460 |
+[trivially copyable]: https://en.cppreference.com/w/cpp/types/is_trivially_copyable |
|
461 |
+[standard-layout]: https://en.cppreference.com/w/cpp/types/is_standard_layout |
|
462 |
+[class]: https://en.cppreference.com/w/cpp/types/is_class |
|
463 |
+[array]: https://en.cppreference.com/w/cpp/types/is_array |
|
464 |
+[scalar]: https://en.cppreference.com/w/cpp/types/is_scalar |
|
465 |
+[`tests/vertex_setup.cpp`]: tests/vertex_setup.cpp |
|
466 |
+[`doc/vertex_setup`]: doc/vertex_setup |
|
467 |
+[`doc/vertex_setup.i`]: doc/vertex_setup.i |
|
468 |
+[Boost.PFR]: https://www.boost.org/libs/pfr |
|
469 |
+[`magic_get`]: https://github.com/apolukhin/magic_get |
|
470 |
+[CppCon 2016: C++14 Reflections Without Macros, Markup nor External Tooling]: https://www.youtube.com/watch?v=abdeAew3gmQ |
|
471 |
+[Meeting C++ 2018: Better C++14 reflections]: https://www.youtube.com/watch?v=UlNUNxLtBI0 |
|
472 |
+ |
|
386 | 473 |
## Building |
387 | 474 |
|
388 | 475 |
See [`BUILDING.md`][]. |
389 | 476 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,22 @@ |
1 |
+#!/bin/sh |
|
2 |
+set -euC |
|
3 |
+ |
|
4 |
+cd "$(dirname "$0")/.." |
|
5 |
+ |
|
6 |
+file="$(basename "$0")" |
|
7 |
+target="gltraits-test-$file" |
|
8 |
+build_dir="_build" |
|
9 |
+in_file="$build_dir/$target" |
|
10 |
+out_file="doc/$file.i" |
|
11 |
+ |
|
12 |
+rm -rf "$build_dir" |
|
13 |
+cmake -B "$build_dir" -DCMAKE_BUILD_TYPE='RelWithDebInfo' |
|
14 |
+cmake --build "$build_dir" --target "$target" |
|
15 |
+ |
|
16 |
+${GDB:-gdb} \ |
|
17 |
+ -n -batch \ |
|
18 |
+ -ex 'set print asm-demangle on' \ |
|
19 |
+ -ex 'disassemble/s main' \ |
|
20 |
+ "$in_file" \ |
|
21 |
+| sed "s|$(pwd)/||;s/^[0-9]\+//" \ |
|
22 |
+>| "$out_file" |
0 | 23 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,508 @@ |
1 |
+Dump of assembler code for function main(): |
|
2 |
+tests/vertex_setup.cpp: |
|
3 |
+ { |
|
4 |
+ 0x0000000000005890 <+0>: endbr64 |
|
5 |
+ 0x0000000000005894 <+4>: push %r14 |
|
6 |
+ 0x0000000000005896 <+6>: push %r13 |
|
7 |
+ 0x0000000000005898 <+8>: push %r12 |
|
8 |
+ 0x000000000000589a <+10>: push %rbp |
|
9 |
+ 0x000000000000589b <+11>: push %rbx |
|
10 |
+ 0x000000000000589c <+12>: sub $0x40,%rsp |
|
11 |
+ |
|
12 |
+_build/_deps/glbase-src/include/glbase.hpp: |
|
13 |
+ GLBASE_GET_GLOBAL(int, debug) |
|
14 |
+ 0x00000000000058a0 <+16>: mov 0x11719(%rip),%r13 # 0x16fc0 |
|
15 |
+ |
|
16 |
+tests/vertex_setup.cpp: |
|
17 |
+ { |
|
18 |
+ 0x00000000000058a7 <+23>: mov %fs:0x28,%rax |
|
19 |
+ 0x00000000000058b0 <+32>: mov %rax,0x38(%rsp) |
|
20 |
+ 0x00000000000058b5 <+37>: xor %eax,%eax |
|
21 |
+ |
|
22 |
+include/gltraits.hpp: |
|
23 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
24 |
+ 0x00000000000058b7 <+39>: test %r13,%r13 |
|
25 |
+ 0x00000000000058ba <+42>: je 0x58c1 <main()+49> |
|
26 |
+ 0x00000000000058bc <+44>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
27 |
+ 0x00000000000058c1 <+49>: mov $0xfffffffffffffff0,%r12 |
|
28 |
+ 0x00000000000058c8 <+56>: mov %fs:(%r12),%r9d |
|
29 |
+ 0x00000000000058cd <+61>: test %r9d,%r9d |
|
30 |
+ 0x00000000000058d0 <+64>: jg 0x5a74 <main()+484> |
|
31 |
+ 0x00000000000058d6 <+70>: mov 0x116f3(%rip),%r14 # 0x16fd0 |
|
32 |
+ 0x00000000000058dd <+77>: xor %r9d,%r9d |
|
33 |
+ 0x00000000000058e0 <+80>: xor %ecx,%ecx |
|
34 |
+ 0x00000000000058e2 <+82>: xor %edi,%edi |
|
35 |
+ 0x00000000000058e4 <+84>: mov $0x68,%r8d |
|
36 |
+ 0x00000000000058ea <+90>: mov $0x1406,%edx |
|
37 |
+ 0x00000000000058ef <+95>: mov $0x3,%esi |
|
38 |
+ 0x00000000000058f4 <+100>: call *(%r14) |
|
39 |
+ 0x00000000000058f7 <+103>: test %r13,%r13 |
|
40 |
+ 0x00000000000058fa <+106>: je 0x5901 <main()+113> |
|
41 |
+ 0x00000000000058fc <+108>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
42 |
+ 0x0000000000005901 <+113>: mov %fs:(%r12),%r8d |
|
43 |
+ 0x0000000000005906 <+118>: test %r8d,%r8d |
|
44 |
+ 0x0000000000005909 <+121>: jg 0x5c01 <main()+881> |
|
45 |
+ 0x000000000000590f <+127>: xor %ecx,%ecx |
|
46 |
+ 0x0000000000005911 <+129>: mov $0xc,%r9d |
|
47 |
+ 0x0000000000005917 <+135>: mov $0x68,%r8d |
|
48 |
+ 0x000000000000591d <+141>: mov $0x1406,%edx |
|
49 |
+ 0x0000000000005922 <+146>: mov $0x2,%esi |
|
50 |
+ 0x0000000000005927 <+151>: mov $0x1,%edi |
|
51 |
+ 0x000000000000592c <+156>: call *(%r14) |
|
52 |
+ |
|
53 |
+ GLTRAITS_VALUE_MATRIXS(glm::mat, FLOAT, glm::value_ptr, GL_FALSE, 32F, f, , , KEEP) |
|
54 |
+ 0x000000000000592f <+159>: test %r13,%r13 |
|
55 |
+ 0x0000000000005932 <+162>: je 0x5939 <main()+169> |
|
56 |
+ 0x0000000000005934 <+164>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
57 |
+ 0x0000000000005939 <+169>: mov %fs:(%r12),%edi |
|
58 |
+ 0x000000000000593e <+174>: test %edi,%edi |
|
59 |
+ 0x0000000000005940 <+176>: jg 0x5bca <main()+826> |
|
60 |
+ |
|
61 |
+tests/vertex_setup.cpp: |
|
62 |
+ { |
|
63 |
+ 0x0000000000005946 <+182>: mov $0x14,%ebx |
|
64 |
+ 0x000000000000594b <+187>: mov $0x2,%ebp |
|
65 |
+ |
|
66 |
+include/gltraits.hpp: |
|
67 |
+ GLTRAITS_VALUE_MATRIXS(glm::mat, FLOAT, glm::value_ptr, GL_FALSE, 32F, f, , , KEEP) |
|
68 |
+ 0x0000000000005950 <+192>: mov %rbx,%r9 |
|
69 |
+ 0x0000000000005953 <+195>: add $0xc,%rbx |
|
70 |
+ 0x0000000000005957 <+199>: mov %ebp,%edi |
|
71 |
+ 0x0000000000005959 <+201>: mov $0x68,%r8d |
|
72 |
+ 0x000000000000595f <+207>: xor %ecx,%ecx |
|
73 |
+ 0x0000000000005961 <+209>: mov $0x1406,%edx |
|
74 |
+ 0x0000000000005966 <+214>: mov $0x3,%esi |
|
75 |
+ 0x000000000000596b <+219>: add $0x1,%ebp |
|
76 |
+ 0x000000000000596e <+222>: call *(%r14) |
|
77 |
+ 0x0000000000005971 <+225>: cmp $0x38,%rbx |
|
78 |
+ 0x0000000000005975 <+229>: jne 0x5950 <main()+192> |
|
79 |
+ |
|
80 |
+ GLTRAITS_VALUE_VECTOR( glm::ivec, INT, glm::value_ptr, 32I, i, I, _INTEGER, OMIT, 2, 0, 3, 0, {}, {}) |
|
81 |
+ 0x0000000000005977 <+231>: test %r13,%r13 |
|
82 |
+ 0x000000000000597a <+234>: je 0x5981 <main()+241> |
|
83 |
+ 0x000000000000597c <+236>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
84 |
+ 0x0000000000005981 <+241>: mov %fs:(%r12),%esi |
|
85 |
+ 0x0000000000005986 <+246>: test %esi,%esi |
|
86 |
+ 0x0000000000005988 <+248>: jg 0x5b93 <main()+771> |
|
87 |
+ 0x000000000000598e <+254>: mov $0x38,%r8d |
|
88 |
+ 0x0000000000005994 <+260>: mov $0x68,%ecx |
|
89 |
+ 0x0000000000005999 <+265>: mov $0x1404,%edx |
|
90 |
+ 0x000000000000599e <+270>: mov 0x11633(%rip),%rbx # 0x16fd8 |
|
91 |
+ 0x00000000000059a5 <+277>: mov $0x4,%esi |
|
92 |
+ 0x00000000000059aa <+282>: mov $0x5,%edi |
|
93 |
+ 0x00000000000059af <+287>: call *(%rbx) |
|
94 |
+ |
|
95 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
96 |
+ 0x00000000000059b1 <+289>: test %r13,%r13 |
|
97 |
+ 0x00000000000059b4 <+292>: je 0x59bb <main()+299> |
|
98 |
+ 0x00000000000059b6 <+294>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
99 |
+ 0x00000000000059bb <+299>: mov %fs:(%r12),%ecx |
|
100 |
+ 0x00000000000059c0 <+304>: test %ecx,%ecx |
|
101 |
+ 0x00000000000059c2 <+306>: jg 0x5b5c <main()+716> |
|
102 |
+ 0x00000000000059c8 <+312>: xor %ecx,%ecx |
|
103 |
+ 0x00000000000059ca <+314>: mov $0x48,%r9d |
|
104 |
+ 0x00000000000059d0 <+320>: mov $0x68,%r8d |
|
105 |
+ 0x00000000000059d6 <+326>: mov $0x1406,%edx |
|
106 |
+ 0x00000000000059db <+331>: mov $0x4,%esi |
|
107 |
+ 0x00000000000059e0 <+336>: mov $0x6,%edi |
|
108 |
+ 0x00000000000059e5 <+341>: call *(%r14) |
|
109 |
+ |
|
110 |
+ GLTRAITS_VALUE_SCALAR( GLubyte, UNSIGNED_BYTE, UNSIGNED_INT, 8UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
111 |
+ 0x00000000000059e8 <+344>: test %r13,%r13 |
|
112 |
+ 0x00000000000059eb <+347>: je 0x59f2 <main()+354> |
|
113 |
+ 0x00000000000059ed <+349>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
114 |
+ 0x00000000000059f2 <+354>: mov %fs:(%r12),%edx |
|
115 |
+ 0x00000000000059f7 <+359>: test %edx,%edx |
|
116 |
+ 0x00000000000059f9 <+361>: jg 0x5b25 <main()+661> |
|
117 |
+ 0x00000000000059ff <+367>: mov $0x58,%r8d |
|
118 |
+ 0x0000000000005a05 <+373>: mov $0x68,%ecx |
|
119 |
+ 0x0000000000005a0a <+378>: mov $0x1401,%edx |
|
120 |
+ 0x0000000000005a0f <+383>: mov $0x1,%esi |
|
121 |
+ 0x0000000000005a14 <+388>: mov $0x7,%edi |
|
122 |
+ 0x0000000000005a19 <+393>: call *(%rbx) |
|
123 |
+ |
|
124 |
+ GLTRAITS_VALUE_SCALAR( GLushort, UNSIGNED_SHORT, UNSIGNED_INT, 16UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
125 |
+ GLTRAITS_VALUE_SCALAR( GLuint, UNSIGNED_INT, UNSIGNED_INT, 32UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
126 |
+ GLTRAITS_VALUE_SCALAR( GLdouble, DOUBLE, DOUBLE, ED, d, L, , OMIT, 4, 0, 4, 1, "GL_ARB_gpu_shader_fp64", "GL_ARB_vertex_attrib_64bit") |
|
127 |
+ 0x0000000000005a1b <+395>: test %r13,%r13 |
|
128 |
+ 0x0000000000005a1e <+398>: je 0x5a25 <main()+405> |
|
129 |
+ 0x0000000000005a20 <+400>: call 0x3480 <TLS init function for GLBase::debug_@plt> |
|
130 |
+ 0x0000000000005a25 <+405>: mov %fs:(%r12),%eax |
|
131 |
+ 0x0000000000005a2a <+410>: test %eax,%eax |
|
132 |
+ 0x0000000000005a2c <+412>: jg 0x5aab <main()+539> |
|
133 |
+ 0x0000000000005a2e <+414>: mov $0x60,%r8d |
|
134 |
+ 0x0000000000005a34 <+420>: mov $0x68,%ecx |
|
135 |
+ 0x0000000000005a39 <+425>: mov $0x140a,%edx |
|
136 |
+ 0x0000000000005a3e <+430>: mov 0x1156b(%rip),%rax # 0x16fb0 |
|
137 |
+ 0x0000000000005a45 <+437>: mov $0x1,%esi |
|
138 |
+ 0x0000000000005a4a <+442>: mov $0x8,%edi |
|
139 |
+ 0x0000000000005a4f <+447>: call *(%rax) |
|
140 |
+ |
|
141 |
+tests/vertex_setup.cpp: |
|
142 |
+ } |
|
143 |
+ 0x0000000000005a51 <+449>: mov 0x38(%rsp),%rax |
|
144 |
+ 0x0000000000005a56 <+454>: sub %fs:0x28,%rax |
|
145 |
+ 0x0000000000005a5f <+463>: jne 0x5c38 <main()+936> |
|
146 |
+ 0x0000000000005a65 <+469>: add $0x40,%rsp |
|
147 |
+ 0x0000000000005a69 <+473>: xor %eax,%eax |
|
148 |
+ 0x0000000000005a6b <+475>: pop %rbx |
|
149 |
+ 0x0000000000005a6c <+476>: pop %rbp |
|
150 |
+ 0x0000000000005a6d <+477>: pop %r12 |
|
151 |
+ 0x0000000000005a6f <+479>: pop %r13 |
|
152 |
+ 0x0000000000005a71 <+481>: pop %r14 |
|
153 |
+ 0x0000000000005a73 <+483>: ret |
|
154 |
+ |
|
155 |
+/usr/include/c++/11/bits/basic_string.h: |
|
156 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
157 |
+ 0x0000000000005a74 <+484>: lea 0x10(%rsp),%rbp |
|
158 |
+ 0x0000000000005a79 <+489>: lea 0x20(%rsp),%rax |
|
159 |
+ |
|
160 |
+include/gltraits.hpp: |
|
161 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
162 |
+ 0x0000000000005a7e <+494>: mov $0x2,%edi |
|
163 |
+ |
|
164 |
+/usr/include/c++/11/bits/basic_string.h: |
|
165 |
+ { _M_string_length = __length; } |
|
166 |
+ 0x0000000000005a83 <+499>: movq $0x0,0x18(%rsp) |
|
167 |
+ |
|
168 |
+include/gltraits.hpp: |
|
169 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
170 |
+ 0x0000000000005a8c <+508>: mov %rbp,%rsi |
|
171 |
+ |
|
172 |
+/usr/include/c++/11/bits/basic_string.h: |
|
173 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
174 |
+ 0x0000000000005a8f <+511>: mov %rax,0x10(%rsp) |
|
175 |
+ |
|
176 |
+/usr/include/c++/11/bits/char_traits.h: |
|
177 |
+ { __c1 = __c2; } |
|
178 |
+ 0x0000000000005a94 <+516>: movb $0x0,0x20(%rsp) |
|
179 |
+ |
|
180 |
+include/gltraits.hpp: |
|
181 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
182 |
+ 0x0000000000005a99 <+521>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
183 |
+ |
|
184 |
+/usr/include/c++/11/bits/basic_string.h: |
|
185 |
+ { _M_dispose(); } |
|
186 |
+ 0x0000000000005a9e <+526>: mov %rbp,%rdi |
|
187 |
+ 0x0000000000005aa1 <+529>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
188 |
+ 0x0000000000005aa6 <+534>: jmp 0x58d6 <main()+70> |
|
189 |
+ |
|
190 |
+ basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) |
|
191 |
+ 0x0000000000005aab <+539>: lea 0x10(%rsp),%rbp |
|
192 |
+ 0x0000000000005ab0 <+544>: lea 0x20(%rsp),%rax |
|
193 |
+ |
|
194 |
+/usr/include/c++/11/bits/basic_string.tcc: |
|
195 |
+ _M_data(_M_create(__dnew, size_type(0))); |
|
196 |
+ 0x0000000000005ab5 <+549>: xor %edx,%edx |
|
197 |
+ |
|
198 |
+ size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); |
|
199 |
+ 0x0000000000005ab7 <+551>: movq $0x1a,0x8(%rsp) |
|
200 |
+ |
|
201 |
+ |
|
202 |
+ if (__dnew > size_type(_S_local_capacity)) |
|
203 |
+ { |
|
204 |
+ _M_data(_M_create(__dnew, size_type(0))); |
|
205 |
+ 0x0000000000005ac0 <+560>: lea 0x8(%rsp),%rsi |
|
206 |
+ 0x0000000000005ac5 <+565>: mov %rbp,%rdi |
|
207 |
+ |
|
208 |
+/usr/include/c++/11/bits/basic_string.h: |
|
209 |
+ : allocator_type(__a), _M_p(__dat) { } |
|
210 |
+ 0x0000000000005ac8 <+568>: mov %rax,0x10(%rsp) |
|
211 |
+ |
|
212 |
+/usr/include/c++/11/bits/basic_string.tcc: |
|
213 |
+ basic_string<_CharT, _Traits, _Alloc>:: |
|
214 |
+ 0x0000000000005acd <+573>: call 0x38a0 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long)@plt> |
|
215 |
+ |
|
216 |
+ _M_capacity(__dnew); |
|
217 |
+ } |
|
218 |
+ |
|
219 |
+ // Check for out_of_range and length_error exceptions. |
|
220 |
+ __try |
|
221 |
+ { this->_S_copy_chars(_M_data(), __beg, __end); } |
|
222 |
+ 0x0000000000005ad2 <+578>: lea 0xb545(%rip),%rdx # 0x1101e |
|
223 |
+ |
|
224 |
+ _M_data(_M_create(__dnew, size_type(0))); |
|
225 |
+ 0x0000000000005ad9 <+585>: mov %rax,%rdi |
|
226 |
+ |
|
227 |
+/usr/include/c++/11/bits/basic_string.h: |
|
228 |
+ { _M_dataplus._M_p = __p; } |
|
229 |
+ 0x0000000000005adc <+588>: mov %rax,0x10(%rsp) |
|
230 |
+ |
|
231 |
+ |
|
232 |
+ pointer |
|
233 |
+ _M_data() const |
|
234 |
+ { return _M_dataplus._M_p; } |
|
235 |
+ |
|
236 |
+ pointer |
|
237 |
+ _M_local_data() |
|
238 |
+ { |
|
239 |
+ #if __cplusplus >= 201103L |
|
240 |
+ return std::pointer_traits<pointer>::pointer_to(*_M_local_buf); |
|
241 |
+ #else |
|
242 |
+ return pointer(_M_local_buf); |
|
243 |
+ #endif |
|
244 |
+ } |
|
245 |
+ |
|
246 |
+ const_pointer |
|
247 |
+ _M_local_data() const |
|
248 |
+ { |
|
249 |
+ #if __cplusplus >= 201103L |
|
250 |
+ return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf); |
|
251 |
+ #else |
|
252 |
+ return const_pointer(_M_local_buf); |
|
253 |
+ #endif |
|
254 |
+ } |
|
255 |
+ |
|
256 |
+ void |
|
257 |
+ _M_capacity(size_type __capacity) |
|
258 |
+ { _M_allocated_capacity = __capacity; } |
|
259 |
+ 0x0000000000005ae1 <+593>: mov 0x8(%rsp),%rax |
|
260 |
+ |
|
261 |
+/usr/include/c++/11/bits/basic_string.tcc: |
|
262 |
+ { this->_S_copy_chars(_M_data(), __beg, __end); } |
|
263 |
+ 0x0000000000005ae6 <+598>: lea -0x1a(%rdx),%rsi |
|
264 |
+ |
|
265 |
+/usr/include/c++/11/bits/basic_string.h: |
|
266 |
+ { _M_allocated_capacity = __capacity; } |
|
267 |
+ 0x0000000000005aea <+602>: mov %rax,0x20(%rsp) |
|
268 |
+ |
|
269 |
+/usr/include/c++/11/bits/basic_string.tcc: |
|
270 |
+ { this->_S_copy_chars(_M_data(), __beg, __end); } |
|
271 |
+ 0x0000000000005aef <+607>: call 0x36c0 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy_chars(char*, char const*, char const*)@plt> |
|
272 |
+ |
|
273 |
+ __catch(...) |
|
274 |
+ { |
|
275 |
+ _M_dispose(); |
|
276 |
+ __throw_exception_again; |
|
277 |
+ } |
|
278 |
+ |
|
279 |
+ _M_set_length(__dnew); |
|
280 |
+ 0x0000000000005af4 <+612>: mov 0x8(%rsp),%rax |
|
281 |
+ |
|
282 |
+/usr/include/c++/11/bits/char_traits.h: |
|
283 |
+ { __c1 = __c2; } |
|
284 |
+ 0x0000000000005af9 <+617>: mov 0x10(%rsp),%rdx |
|
285 |
+ |
|
286 |
+include/gltraits.hpp: |
|
287 |
+ GLTRAITS_VALUE_SCALAR( GLdouble, DOUBLE, DOUBLE, ED, d, L, , OMIT, 4, 0, 4, 1, "GL_ARB_gpu_shader_fp64", "GL_ARB_vertex_attrib_64bit") |
|
288 |
+ 0x0000000000005afe <+622>: mov %rbp,%rsi |
|
289 |
+ 0x0000000000005b01 <+625>: mov $0x40000001,%edi |
|
290 |
+ |
|
291 |
+/usr/include/c++/11/bits/basic_string.h: |
|
292 |
+ { _M_string_length = __length; } |
|
293 |
+ 0x0000000000005b06 <+630>: mov %rax,0x18(%rsp) |
|
294 |
+ |
|
295 |
+include/gltraits.hpp: |
|
296 |
+ GLTRAITS_VALUE_SCALAR( GLdouble, DOUBLE, DOUBLE, ED, d, L, , OMIT, 4, 0, 4, 1, "GL_ARB_gpu_shader_fp64", "GL_ARB_vertex_attrib_64bit") |
|
297 |
+ 0x0000000000005b0b <+635>: shl $0x2,%rdi |
|
298 |
+ |
|
299 |
+/usr/include/c++/11/bits/char_traits.h: |
|
300 |
+ { __c1 = __c2; } |
|
301 |
+ 0x0000000000005b0f <+639>: movb $0x0,(%rdx,%rax,1) |
|
302 |
+ |
|
303 |
+include/gltraits.hpp: |
|
304 |
+ GLTRAITS_VALUE_SCALAR( GLdouble, DOUBLE, DOUBLE, ED, d, L, , OMIT, 4, 0, 4, 1, "GL_ARB_gpu_shader_fp64", "GL_ARB_vertex_attrib_64bit") |
|
305 |
+ 0x0000000000005b13 <+643>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
306 |
+ |
|
307 |
+/usr/include/c++/11/bits/basic_string.h: |
|
308 |
+ { _M_dispose(); } |
|
309 |
+ 0x0000000000005b18 <+648>: mov %rbp,%rdi |
|
310 |
+ 0x0000000000005b1b <+651>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
311 |
+ 0x0000000000005b20 <+656>: jmp 0x5a2e <main()+414> |
|
312 |
+ |
|
313 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
314 |
+ 0x0000000000005b25 <+661>: lea 0x10(%rsp),%rbp |
|
315 |
+ 0x0000000000005b2a <+666>: lea 0x20(%rsp),%rax |
|
316 |
+ |
|
317 |
+include/gltraits.hpp: |
|
318 |
+ GLTRAITS_VALUE_SCALAR( GLubyte, UNSIGNED_BYTE, UNSIGNED_INT, 8UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
319 |
+ 0x0000000000005b2f <+671>: mov $0x3,%edi |
|
320 |
+ |
|
321 |
+/usr/include/c++/11/bits/basic_string.h: |
|
322 |
+ { _M_string_length = __length; } |
|
323 |
+ 0x0000000000005b34 <+676>: movq $0x0,0x18(%rsp) |
|
324 |
+ |
|
325 |
+include/gltraits.hpp: |
|
326 |
+ GLTRAITS_VALUE_SCALAR( GLubyte, UNSIGNED_BYTE, UNSIGNED_INT, 8UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
327 |
+ 0x0000000000005b3d <+685>: mov %rbp,%rsi |
|
328 |
+ |
|
329 |
+/usr/include/c++/11/bits/basic_string.h: |
|
330 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
331 |
+ 0x0000000000005b40 <+688>: mov %rax,0x10(%rsp) |
|
332 |
+ |
|
333 |
+/usr/include/c++/11/bits/char_traits.h: |
|
334 |
+ { __c1 = __c2; } |
|
335 |
+ 0x0000000000005b45 <+693>: movb $0x0,0x20(%rsp) |
|
336 |
+ |
|
337 |
+include/gltraits.hpp: |
|
338 |
+ GLTRAITS_VALUE_SCALAR( GLubyte, UNSIGNED_BYTE, UNSIGNED_INT, 8UI, ui, I, _INTEGER, OMIT, 3, 0, 3, 0, {}, {}) |
|
339 |
+ 0x0000000000005b4a <+698>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
340 |
+ |
|
341 |
+/usr/include/c++/11/bits/basic_string.h: |
|
342 |
+ { _M_dispose(); } |
|
343 |
+ 0x0000000000005b4f <+703>: mov %rbp,%rdi |
|
344 |
+ 0x0000000000005b52 <+706>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
345 |
+ 0x0000000000005b57 <+711>: jmp 0x59ff <main()+367> |
|
346 |
+ |
|
347 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
348 |
+ 0x0000000000005b5c <+716>: lea 0x10(%rsp),%rbp |
|
349 |
+ 0x0000000000005b61 <+721>: lea 0x20(%rsp),%rax |
|
350 |
+ |
|
351 |
+include/gltraits.hpp: |
|
352 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
353 |
+ 0x0000000000005b66 <+726>: mov $0x2,%edi |
|
354 |
+ |
|
355 |
+/usr/include/c++/11/bits/basic_string.h: |
|
356 |
+ { _M_string_length = __length; } |
|
357 |
+ 0x0000000000005b6b <+731>: movq $0x0,0x18(%rsp) |
|
358 |
+ |
|
359 |
+include/gltraits.hpp: |
|
360 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
361 |
+ 0x0000000000005b74 <+740>: mov %rbp,%rsi |
|
362 |
+ |
|
363 |
+/usr/include/c++/11/bits/basic_string.h: |
|
364 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
365 |
+ 0x0000000000005b77 <+743>: mov %rax,0x10(%rsp) |
|
366 |
+ |
|
367 |
+/usr/include/c++/11/bits/char_traits.h: |
|
368 |
+ { __c1 = __c2; } |
|
369 |
+ 0x0000000000005b7c <+748>: movb $0x0,0x20(%rsp) |
|
370 |
+ |
|
371 |
+include/gltraits.hpp: |
|
372 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
373 |
+ 0x0000000000005b81 <+753>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
374 |
+ |
|
375 |
+/usr/include/c++/11/bits/basic_string.h: |
|
376 |
+ { _M_dispose(); } |
|
377 |
+ 0x0000000000005b86 <+758>: mov %rbp,%rdi |
|
378 |
+ 0x0000000000005b89 <+761>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
379 |
+ 0x0000000000005b8e <+766>: jmp 0x59c8 <main()+312> |
|
380 |
+ |
|
381 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
382 |
+ 0x0000000000005b93 <+771>: lea 0x10(%rsp),%rbp |
|
383 |
+ 0x0000000000005b98 <+776>: lea 0x20(%rsp),%rax |
|
384 |
+ |
|
385 |
+include/gltraits.hpp: |
|
386 |
+ GLTRAITS_VALUE_VECTOR( glm::ivec, INT, glm::value_ptr, 32I, i, I, _INTEGER, OMIT, 2, 0, 3, 0, {}, {}) |
|
387 |
+ 0x0000000000005b9d <+781>: mov $0x3,%edi |
|
388 |
+ |
|
389 |
+/usr/include/c++/11/bits/basic_string.h: |
|
390 |
+ { _M_string_length = __length; } |
|
391 |
+ 0x0000000000005ba2 <+786>: movq $0x0,0x18(%rsp) |
|
392 |
+ |
|
393 |
+include/gltraits.hpp: |
|
394 |
+ GLTRAITS_VALUE_VECTOR( glm::ivec, INT, glm::value_ptr, 32I, i, I, _INTEGER, OMIT, 2, 0, 3, 0, {}, {}) |
|
395 |
+ 0x0000000000005bab <+795>: mov %rbp,%rsi |
|
396 |
+ |
|
397 |
+/usr/include/c++/11/bits/basic_string.h: |
|
398 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
399 |
+ 0x0000000000005bae <+798>: mov %rax,0x10(%rsp) |
|
400 |
+ |
|
401 |
+/usr/include/c++/11/bits/char_traits.h: |
|
402 |
+ { __c1 = __c2; } |
|
403 |
+ 0x0000000000005bb3 <+803>: movb $0x0,0x20(%rsp) |
|
404 |
+ |
|
405 |
+include/gltraits.hpp: |
|
406 |
+ GLTRAITS_VALUE_VECTOR( glm::ivec, INT, glm::value_ptr, 32I, i, I, _INTEGER, OMIT, 2, 0, 3, 0, {}, {}) |
|
407 |
+ 0x0000000000005bb8 <+808>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
408 |
+ |
|
409 |
+/usr/include/c++/11/bits/basic_string.h: |
|
410 |
+ { _M_dispose(); } |
|
411 |
+ 0x0000000000005bbd <+813>: mov %rbp,%rdi |
|
412 |
+ 0x0000000000005bc0 <+816>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
413 |
+ 0x0000000000005bc5 <+821>: jmp 0x598e <main()+254> |
|
414 |
+ |
|
415 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
416 |
+ 0x0000000000005bca <+826>: lea 0x10(%rsp),%rbp |
|
417 |
+ 0x0000000000005bcf <+831>: lea 0x20(%rsp),%rax |
|
418 |
+ |
|
419 |
+include/gltraits.hpp: |
|
420 |
+ GLTRAITS_VALUE_MATRIXS(glm::mat, FLOAT, glm::value_ptr, GL_FALSE, 32F, f, , , KEEP) |
|
421 |
+ 0x0000000000005bd4 <+836>: mov $0x2,%edi |
|
422 |
+ |
|
423 |
+/usr/include/c++/11/bits/basic_string.h: |
|
424 |
+ { _M_string_length = __length; } |
|
425 |
+ 0x0000000000005bd9 <+841>: movq $0x0,0x18(%rsp) |
|
426 |
+ |
|
427 |
+include/gltraits.hpp: |
|
428 |
+ GLTRAITS_VALUE_MATRIXS(glm::mat, FLOAT, glm::value_ptr, GL_FALSE, 32F, f, , , KEEP) |
|
429 |
+ 0x0000000000005be2 <+850>: mov %rbp,%rsi |
|
430 |
+ |
|
431 |
+/usr/include/c++/11/bits/basic_string.h: |
|
432 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
433 |
+ 0x0000000000005be5 <+853>: mov %rax,0x10(%rsp) |
|
434 |
+ |
|
435 |
+/usr/include/c++/11/bits/char_traits.h: |
|
436 |
+ { __c1 = __c2; } |
|
437 |
+ 0x0000000000005bea <+858>: movb $0x0,0x20(%rsp) |
|
438 |
+ |
|
439 |
+include/gltraits.hpp: |
|
440 |
+ GLTRAITS_VALUE_MATRIXS(glm::mat, FLOAT, glm::value_ptr, GL_FALSE, 32F, f, , , KEEP) |
|
441 |
+ 0x0000000000005bef <+863>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
442 |
+ |
|
443 |
+/usr/include/c++/11/bits/basic_string.h: |
|
444 |
+ { _M_dispose(); } |
|
445 |
+ 0x0000000000005bf4 <+868>: mov %rbp,%rdi |
|
446 |
+ 0x0000000000005bf7 <+871>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
447 |
+ 0x0000000000005bfc <+876>: jmp 0x5946 <main()+182> |
|
448 |
+ |
|
449 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
450 |
+ 0x0000000000005c01 <+881>: lea 0x10(%rsp),%rbp |
|
451 |
+ 0x0000000000005c06 <+886>: lea 0x20(%rsp),%rax |
|
452 |
+ |
|
453 |
+include/gltraits.hpp: |
|
454 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
455 |
+ 0x0000000000005c0b <+891>: mov $0x2,%edi |
|
456 |
+ |
|
457 |
+/usr/include/c++/11/bits/basic_string.h: |
|
458 |
+ { _M_string_length = __length; } |
|
459 |
+ 0x0000000000005c10 <+896>: movq $0x0,0x18(%rsp) |
|
460 |
+ |
|
461 |
+include/gltraits.hpp: |
|
462 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
463 |
+ 0x0000000000005c19 <+905>: mov %rbp,%rsi |
|
464 |
+ |
|
465 |
+/usr/include/c++/11/bits/basic_string.h: |
|
466 |
+ : allocator_type(std::move(__a)), _M_p(__dat) { } |
|
467 |
+ 0x0000000000005c1c <+908>: mov %rax,0x10(%rsp) |
|
468 |
+ |
|
469 |
+/usr/include/c++/11/bits/char_traits.h: |
|
470 |
+ { __c1 = __c2; } |
|
471 |
+ 0x0000000000005c21 <+913>: movb $0x0,0x20(%rsp) |
|
472 |
+ |
|
473 |
+include/gltraits.hpp: |
|
474 |
+ GLTRAITS_VALUE_VECTOR( glm::vec, FLOAT, glm::value_ptr, 32F, f, , , KEEP, 2, 0, 2, 0, {}, {}) |
|
475 |
+ 0x0000000000005c26 <+918>: call 0xebc0 <GLBase::check_supported(std::array<int, 2ul>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)> |
|
476 |
+ |
|
477 |
+/usr/include/c++/11/bits/basic_string.h: |
|
478 |
+ { _M_dispose(); } |
|
479 |
+ 0x0000000000005c2b <+923>: mov %rbp,%rdi |
|
480 |
+ 0x0000000000005c2e <+926>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
481 |
+ 0x0000000000005c33 <+931>: jmp 0x590f <main()+127> |
|
482 |
+ |
|
483 |
+tests/vertex_setup.cpp: |
|
484 |
+ } |
|
485 |
+ 0x0000000000005c38 <+936>: call 0x36e0 <__stack_chk_fail@plt> |
|
486 |
+ 0x0000000000005c3d <+941>: endbr64 |
|
487 |
+ |
|
488 |
+/usr/include/c++/11/bits/basic_string.h: |
|
489 |
+ { _M_dispose(); } |
|
490 |
+ 0x0000000000005c41 <+945>: mov %rax,%r12 |
|
491 |
+ 0x0000000000005c44 <+948>: jmp 0x5c6a <main()+986> |
|
492 |
+ 0x0000000000005c46 <+950>: endbr64 |
|
493 |
+ 0x0000000000005c4a <+954>: jmp 0x5c41 <main()+945> |
|
494 |
+ 0x0000000000005c4c <+956>: endbr64 |
|
495 |
+ 0x0000000000005c50 <+960>: jmp 0x5c41 <main()+945> |
|
496 |
+ 0x0000000000005c52 <+962>: endbr64 |
|
497 |
+ 0x0000000000005c56 <+966>: jmp 0x5c41 <main()+945> |
|
498 |
+ 0x0000000000005c58 <+968>: endbr64 |
|
499 |
+ 0x0000000000005c5c <+972>: jmp 0x5c41 <main()+945> |
|
500 |
+ 0x0000000000005c5e <+974>: endbr64 |
|
501 |
+ 0x0000000000005c62 <+978>: jmp 0x5c41 <main()+945> |
|
502 |
+ 0x0000000000005c64 <+980>: endbr64 |
|
503 |
+ 0x0000000000005c68 <+984>: jmp 0x5c41 <main()+945> |
|
504 |
+ 0x0000000000005c6a <+986>: mov %rbp,%rdi |
|
505 |
+ 0x0000000000005c6d <+989>: call 0x3710 <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose()@plt> |
|
506 |
+ 0x0000000000005c72 <+994>: mov %r12,%rdi |
|
507 |
+ 0x0000000000005c75 <+997>: call 0x3890 <_Unwind_Resume@plt> |
|
508 |
+End of assembler dump. |
... | ... |
@@ -38,6 +38,28 @@ public: |
38 | 38 |
template<std::size_t N> |
39 | 39 |
struct Texture; |
40 | 40 |
|
41 |
+ //// Member |
|
42 |
+ |
|
43 |
+ #if __cplusplus >= 201402L |
|
44 |
+ |
|
45 |
+ template<typename... Value> |
|
46 |
+ struct Members |
|
47 |
+ {}; |
|
48 |
+ |
|
49 |
+ template<typename T> |
|
50 |
+ static constexpr auto members() |
|
51 |
+ { |
|
52 |
+ static_assert( |
|
53 |
+ !std::is_empty<T>::value && |
|
54 |
+ std::is_trivially_copyable<T>::value && |
|
55 |
+ std::is_standard_layout<T>::value, |
|
56 |
+ "T must be a non-empty trivially copyable standard-layout type" |
|
57 |
+ ); |
|
58 |
+ return members_<T>(MakeIndices<member_count<T>()>{}); |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ #endif |
|
62 |
+ |
|
41 | 63 |
private: |
42 | 64 |
|
43 | 65 |
//// Helpers |
... | ... |
@@ -71,6 +93,72 @@ private: |
71 | 93 |
> |
72 | 94 |
struct Texture_; |
73 | 95 |
|
96 |
+ //// Member |
|
97 |
+ |
|
98 |
+ // Stripped down version of Boost::PFR. |
|
99 |
+ |
|
100 |
+ #if __cplusplus >= 201402L |
|
101 |
+ |
|
102 |
+ struct MemberInfo |
|
103 |
+ { |
|
104 |
+ GLenum id; |
|
105 |
+ }; |
|
106 |
+ |
|
107 |
+ template<std::size_t N> |
|
108 |
+ struct MemberInfos |
|
109 |
+ { |
|
110 |
+ MemberInfo infos[N]; |
|
111 |
+ }; |
|
112 |
+ |
|
113 |
+ struct MemberAny |
|
114 |
+ { |
|
115 |
+ MemberInfo * info; |
|
116 |
+ |
|
117 |
+ template<typename Value> |
|
118 |
+ constexpr operator Value() |
|
119 |
+ { |
|
120 |
+ return ( |
|
121 |
+ info->id = GLTraits::Value<Value>::id, |
|
122 |
+ Value{} |
|
123 |
+ ); |
|
124 |
+ } |
|
125 |
+ }; |
|
126 |
+ |
|
127 |
+ template<typename T, std::size_t I0, std::size_t... Is> |
|
128 |
+ static constexpr auto member_count_(Indices<I0, Is...>) |
|
129 |
+ -> decltype(T{(I0, MemberAny{}), (Is, MemberAny{})...}, std::size_t{}) |
|
130 |
+ { |
|
131 |
+ return 1 + sizeof...(Is); |
|
132 |
+ } |
|
133 |
+ |
|
134 |
+ template<typename T, std::size_t... Is> |
|
135 |
+ static constexpr auto member_count_(Indices<Is...>) |
|
136 |
+ { |
|
137 |
+ return member_count_<T>(MakeIndices<sizeof...(Is) - 1>{}); |
|
138 |
+ } |
|
139 |
+ |
|
140 |
+ template<typename T> |
|
141 |
+ static constexpr auto member_count() |
|
142 |
+ { |
|
143 |
+ return member_count_<T>(MakeIndices<sizeof(T)>{}); |
|
144 |
+ } |
|
145 |
+ |
|
146 |
+ template<typename T, std::size_t... Is> |
|
147 |
+ static constexpr auto member_infos(MemberInfos<sizeof...(Is)> infos = {}) |
|
148 |
+ { |
|
149 |
+ return ((void)T{MemberAny{&infos.infos[Is]}...}, infos); |
|
150 |
+ } |
|
151 |
+ |
|
152 |
+ template<typename T, std::size_t... Is> |
|
153 |
+ static constexpr auto members_(Indices<Is...>) |
|
154 |
+ { |
|
155 |
+ return Members< |
|
156 |
+ typename ValueID<member_infos<T, Is...>().infos[Is].id>::Value... |
|
157 |
+ >{}; |
|
158 |
+ } |
|
159 |
+ |
|
160 |
+ #endif |
|
161 |
+ |
|
74 | 162 |
}; |
75 | 163 |
|
76 | 164 |
//// Helpers |
... | ... |
@@ -1,3 +1,4 @@ |
1 |
+#include <cstddef> |
|
1 | 2 |
#include <iomanip> |
2 | 3 |
#include <iostream> |
3 | 4 |
#include <string> |
... | ... |
@@ -108,6 +109,40 @@ struct GLTraitsTest : protected GLBase |
108 | 109 |
GLTRAITS_TEST_TEXTURE(compressed_texture_sub_image); |
109 | 110 |
} |
110 | 111 |
|
112 |
+ #if __cplusplus >= 201402L |
|
113 |
+ template< |
|
114 |
+ typename Value, |
|
115 |
+ typename... Values |
|
116 |
+ > |
|
117 |
+ void static test_members( |
|
118 |
+ GLTraits::Members<Value, Values...>, |
|
119 |
+ std::size_t offset = 0 |
|
120 |
+ ) |
|
121 |
+ { |
|
122 |
+ auto unaligned = offset % alignof(Value); |
|
123 |
+ if (unaligned) |
|
124 |
+ offset += alignof(Value) - unaligned; |
|
125 |
+ auto end = offset + sizeof(Value); |
|
126 |
+ using Traits = GLTraits::Value<Value>; |
|
127 |
+ static_assert( |
|
128 |
+ std::is_empty<GLTraits::Members< |
|
129 |
+ Value, Values... |
|
130 |
+ >>::value, |
|
131 |
+ "GLTraits::Members must be empty" |
|
132 |
+ ); |
|
133 |
+ #define GLTRAITS_TEST_MEMBERS(IND, NAME, OFFSET, END) \ |
|
134 |
+ std::cout \ |
|
135 |
+ << std::left << std::setw(IND) << "" \ |
|
136 |
+ << std::left << std::setw(12 - IND) << NAME << " " \ |
|
137 |
+ << std::right << std::setw(2) << std::dec << OFFSET << " " \ |
|
138 |
+ << std::right << std::setw(3) << std::dec << END << "\n"; |
|
139 |
+ GLTRAITS_TEST_MEMBERS(2, Traits::name, offset, end) |
|
140 |
+ test_members(GLTraits::Members<Values...>{}, end); |
|
141 |
+ } |
|
142 |
+ void static test_members(GLTraits::Members<>, std::size_t) |
|
143 |
+ {} |
|
144 |
+ #endif |
|
145 |
+ |
|
111 | 146 |
}; |
112 | 147 |
|
113 | 148 |
|
... | ... |
@@ -135,4 +170,36 @@ int main() |
135 | 170 |
GLTraitsTest::test_texture<1>(); |
136 | 171 |
GLTraitsTest::test_texture<2>(); |
137 | 172 |
GLTraitsTest::test_texture<3>(); |
173 |
+ |
|
174 |
+ #if __cplusplus >= 201402L |
|
175 |
+ struct Vertex |
|
176 |
+ { |
|
177 |
+ glm::vec3 position; |
|
178 |
+ glm::vec2 tex_coord; |
|
179 |
+ glm::mat3 tbn; |
|
180 |
+ glm::ivec4 bone_indices; |
|
181 |
+ glm::vec4 bone_weights; |
|
182 |
+ GLubyte flags; |
|
183 |
+ GLdouble unaligned; |
|
184 |
+ }; |
|
185 |
+ #define GLTRAITS_TEST_MEMBERS_T(T) \ |
|
186 |
+ GLTRAITS_TEST_MEMBERS(0, #T, 0, sizeof(T)) |
|
187 |
+ #define GLTRAITS_TEST_MEMBERS_OFFSETOF(T, MEMBER) \ |
|
188 |
+ GLTRAITS_TEST_MEMBERS( \ |
|
189 |
+ 2, \ |
|
190 |
+ GLTraits::Value<decltype(T::MEMBER)>::name, \ |
|
191 |
+ offsetof(T, MEMBER), \ |
|
192 |
+ offsetof(T, MEMBER) + sizeof(T::MEMBER) \ |
|
193 |
+ ) |
|
194 |
+ GLTRAITS_TEST_MEMBERS_T(Vertex) |
|
195 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, position) |
|
196 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, tex_coord) |
|
197 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, tbn) |
|
198 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, bone_indices) |
|
199 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, bone_weights) |
|
200 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, flags) |
|
201 |
+ GLTRAITS_TEST_MEMBERS_OFFSETOF(Vertex, unaligned) |
|
202 |
+ GLTRAITS_TEST_MEMBERS_T(Vertex) |
|
203 |
+ GLTraitsTest::test_members(GLTraits::members<Vertex>()); |
|
204 |
+ #endif |
|
138 | 205 |
} |
139 | 206 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,48 @@ |
1 |
+#include <cstddef> |
|
2 |
+ |
|
3 |
+#include <glm/glm.hpp> |
|
4 |
+ |
|
5 |
+#include <glbase.hpp> |
|
6 |
+#include <gltraits.hpp> |
|
7 |
+ |
|
8 |
+ |
|
9 |
+template< |
|
10 |
+ typename Value, |
|
11 |
+ typename... Values |
|
12 |
+> |
|
13 |
+void vertex_setup( |
|
14 |
+ GLTraits::Members<Value, Values...>, |
|
15 |
+ std::size_t stride, |
|
16 |
+ std::size_t offset = 0, |
|
17 |
+ GLint location = 0 |
|
18 |
+) |
|
19 |
+{ |
|
20 |
+ auto unaligned = offset % alignof(Value); |
|
21 |
+ if (unaligned) |
|
22 |
+ offset += alignof(Value) - unaligned; |
|
23 |
+ GLTraits::Value<Value>::vertex_attrib_pointer(location, offset, stride); |
|
24 |
+ vertex_setup( |
|
25 |
+ GLTraits::Members<Values...>{}, |
|
26 |
+ stride, |
|
27 |
+ offset + sizeof(Value), |
|
28 |
+ location + GLTraits::Value<Value>::columns |
|
29 |
+ ); |
|
30 |
+} |
|
31 |
+void vertex_setup(GLTraits::Members<>, std::size_t, std::size_t, GLint) |
|
32 |
+{} |
|
33 |
+ |
|
34 |
+ |
|
35 |
+int main() |
|
36 |
+{ |
|
37 |
+ struct Vertex |
|
38 |
+ { |
|
39 |
+ glm::vec3 position; |
|
40 |
+ glm::vec2 tex_coord; |
|
41 |
+ glm::mat3 tbn; |
|
42 |
+ glm::ivec4 bone_indices; |
|
43 |
+ glm::vec4 bone_weights; |
|
44 |
+ GLubyte flags; |
|
45 |
+ GLdouble unaligned; |
|
46 |
+ }; |
|
47 |
+ vertex_setup(GLTraits::members<Vertex>(), sizeof(Vertex)); |
|
48 |
+} |