#pragma once #include #include #include #include #define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \ struct name_ { \ using Type = ::mbgl::gfx::AttributeType; \ static auto name() { \ return #name_; \ } \ } namespace mbgl { namespace gfx { template class AttributeType { public: using ValueType = T; static constexpr size_t Dimensions = N; using Value = std::array; }; // Attribute binding requires member offsets. The only standard way to // obtain an offset is the offsetof macro. The offsetof macro has defined // behavior only for standard layout types. That rules out std::tuple and // any other solution that relies on chained inheritance. Manually implemented // variadic specialization looks like the only solution. Fortunately, we // only use a maximum of five attributes. namespace detail { template class Vertex; template <> class Vertex<> { public: using VertexType = Vertex<>; }; template class Vertex { public: A1 a1; using VertexType = Vertex; static const std::size_t attributeOffsets[1]; }; template class Vertex { public: A1 a1; A2 a2; using VertexType = Vertex; static const std::size_t attributeOffsets[2]; }; template class Vertex { public: A1 a1; A2 a2; A3 a3; using VertexType = Vertex; static const std::size_t attributeOffsets[3]; }; template class Vertex { public: A1 a1; A2 a2; A3 a3; A4 a4; using VertexType = Vertex; static const std::size_t attributeOffsets[4]; }; template class Vertex { public: A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; using VertexType = Vertex; static const std::size_t attributeOffsets[5]; }; template const std::size_t Vertex::attributeOffsets[1] = { offsetof(VertexType, a1) }; template const std::size_t Vertex::attributeOffsets[2] = { offsetof(VertexType, a1), offsetof(VertexType, a2) }; template const std::size_t Vertex::attributeOffsets[3] = { offsetof(VertexType, a1), offsetof(VertexType, a2), offsetof(VertexType, a3) }; template const std::size_t Vertex::attributeOffsets[4] = { offsetof(VertexType, a1), offsetof(VertexType, a2), offsetof(VertexType, a3), offsetof(VertexType, a4) }; template const std::size_t Vertex::attributeOffsets[5] = { offsetof(VertexType, a1), offsetof(VertexType, a2), offsetof(VertexType, a3), offsetof(VertexType, a4), offsetof(VertexType, a5) }; template class Vertex> { public: using VertexType = Vertex; }; } // namespace detail template using Vertex = typename detail::Vertex::VertexType; } // namespace gfx } // namespace mbgl