Skip to content

Instantly share code, notes, and snippets.

@peteb
Created May 10, 2011 09:28
Show Gist options
  • Save peteb/964164 to your computer and use it in GitHub Desktop.
Save peteb/964164 to your computer and use it in GitHub Desktop.
C++ templates for vector classes (vec3, color4, float2, etc)
#include <iostream>
#include <ctime>
#include <iterator>
// old stuff
template<typename DataType, int NumComponents, typename Derived>
struct composite_base {
typedef DataType value_type;
static const int num_components = NumComponents;
inline Derived &operator *= (DataType rhs) {
for (int i = 0; i < NumComponents; ++i)
derived().vals[i] *= rhs;
return derived();
}
private:
Derived &derived() {return static_cast<Derived &>(*this); }
};
template<typename T>
struct composite3 : public composite_base<T, 3, composite3<T> > {
composite3(T x, T y, T z)
: x(x), y(y), z(z) {}
union {
struct {T r, g, b; };
struct {T x, y, z; };
T vals[3];
};
};
typedef composite3<int> int3;
// new stuff
template<int Level, typename DataType>
struct named_component {
named_component(DataType val) : val(val) {}
named_component() = default;
DataType val;
};
template<typename DataType> struct named_component<1, DataType> {
named_component(DataType val) : val(val) {}
named_component() = default;
union {DataType val, x, r, s; };
};
template<typename DataType> struct named_component<2, DataType> {
named_component(DataType val) : val(val) {}
named_component() = default;
union {DataType val, y, g, t; };
};
template<typename DataType> struct named_component<3, DataType> {
named_component(DataType val) : val(val) {}
named_component() = default;
union {DataType val, z, b, p; };
};
template<typename DataType> struct named_component<4, DataType> {
named_component(DataType val) : val(val) {}
named_component() = default;
union {DataType val, w, a, q; };
};
// component here is really component_list, and named_component could be component
template<int Level, typename DataType>
struct component : public component<Level-1, DataType>, public named_component<Level, DataType> {
constexpr static int size = Level;
component(std::initializer_list<DataType> s)
: component<size-1, DataType>(s)
, named_component<Level, DataType>(*(s.begin() + size-1)) {}
component() = default;
component(const component<size-1, DataType> &prev, DataType value)
: component<size-1, DataType>(prev), named_component<Level, DataType>(value) {}
component<size+1, DataType> operator()(DataType value) const {
return component<size+1, DataType>(*this, value);
}
component<size, DataType> &operator *=(DataType value) {
component<size-1, DataType>::operator *=(value);
named_component<size, DataType>::val *= value;
return *this;
}
};
template<typename DataType>
struct component<1, DataType> : public named_component<1, DataType> {
component() = default;
component(DataType value)
: named_component<1, DataType>(value) {}
component(std::initializer_list<DataType> s)
: named_component<1, DataType>(*s.begin()) {}
constexpr static int size = 1;
const DataType *data() const {const DataType &blaurgh = named_component<1, DataType>::val; return &blaurgh; }
component<2, DataType> operator()(DataType value) const {
return component<2, DataType>(*this, value);
}
component<1, DataType> &operator *=(DataType value) {
named_component<1, DataType>::val *= value;
return *this;
}
};
template<typename DataType>
struct component<0, DataType> {
component() = default;
component<1, DataType> operator()(DataType value) const {
return component<1, DataType>(value);
}
};
// template<typename DataType>
// inline component<1, DataType> vec(DataType value) {
// return component<1, DataType>(value);
// }
int main() {
component<4, float> list = {1.0f, 2.0f, 3.0f, 4.0f};
list *= 10.0f;
std::cout << "x: " << list.x << " y: " << list.y << " z: " << list.z << " w: " << list.w << std::endl;
std::copy(list.data(), list.data() + list.size, std::ostream_iterator<float>(std::cout, "\n"));
clock_t start = clock();
int3 last(0, 0, 0);
component<3, int> tja = {1, 2, 3};
for (size_t i = 0; i < 499999999; ++i) {
tja.x = 2; // = component<3, int>{2, 3, 4};
tja.y = 3;
tja.z = 4;
tja *= 2;
last.x = tja.x;
}
clock_t end = clock();
std::cout << last.x << std::endl;
std::cout << "diff t: " << end - start << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment