Skip to content

Instantly share code, notes, and snippets.

@usagi
Last active December 14, 2015 04:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usagi/5027828 to your computer and use it in GitHub Desktop.
Save usagi/5027828 to your computer and use it in GitHub Desktop.
the vertex (attribute) type sample for libWRP-GLEW.
#include <cstddef>
#include <cstdint>
#include <memory>
template<class T, class ... TS>
struct vertex final
{
static constexpr size_t elements = 1 + sizeof...(TS);
// fix1-1: remove this line
// static constexpr size_t size = sizeof(T) + vertex<TS...>::size;
private:
template<size_t N, class T_, class ... TS_>
struct offset_of_
{
using type = typename offset_of_<N - 1, TS_ ...>::type;
static constexpr size_t add_offset = sizeof(T_) + offset_of_<N - 1, TS_ ...>::add_offset;
};
template<class T_, class ... TS_>
struct offset_of_<0, T_, TS_ ...>
{
using type = T_;
static constexpr size_t add_offset = 0;
};
public:
template<size_t N>
struct offset_of
{
using type = typename offset_of_<N, T, TS ...>::type;
static constexpr size_t value = offset_of_<N, T, TS ...>::add_offset;
};
template<size_t N>
typename offset_of<N>::type & element_of()
{ return *reinterpret_cast<typename offset_of<N>::type*>(&data_[offset_of<N>::value]); }
template<size_t N>
void element_of(typename offset_of<N>::type&& a)
{ *reinterpret_cast<typename offset_of<N>::type*>(&data_[offset_of<N>::value]) = std::move(a); }
template<size_t N>
void element_of(const typename offset_of<N>::type& a)
{ *reinterpret_cast<typename offset_of<N>::type*>(&data_[offset_of<N>::value]) = a; }
// fix1-2: add four line
static constexpr size_t size
= offset_of<sizeof...(TS)>::value
+ sizeof(typename offset_of<sizeof...(TS)>::type)
;
private:
std::array<uint8_t, size> data_;
public:
decltype(data_.data()) data() const { return data_.data(); }
decltype(data_.begin()) begin() { return data_.begin(); }
decltype(data_.end()) end() { return data_.end(); }
decltype(data_.cbegin()) cbegin() const { return data_.cbegin(); }
decltype(data_.cend()) cend() const { return data_.cend(); }
vertex(){ }
vertex(const T& v0, const TS& ... vs) { initialize<0, T, TS...>(v0, vs...); }
private:
template<size_t N> void initialize() const { }
template<size_t N, class T_, class ... TS_>
void initialize(const T_& v, const TS_& ... vs)
{
element_of<N>(std::move(v));
if(sizeof...(TS_))
initialize<N + 1, TS_...>(vs...);
}
};
template<class T> struct vertex<T> final
{
static constexpr size_t elements = 1;
static constexpr size_t size = sizeof(int);
vertex() { }
vertex(const T& v0) : data_(v0) { }
const uint8_t* const data() const { return reinterpret_cast<uint8_t*>(&data_); }
const uint8_t* begin() { return data_.data(); }
const uint8_t* end() { return data_.data() + 1; }
const uint8_t* const cbegin() const { return data_.begin(); }
const uint8_t* cend() const { return data_.end(); }
private:
T data_;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment