Created
May 10, 2011 09:28
-
-
Save peteb/964164 to your computer and use it in GitHub Desktop.
C++ templates for vector classes (vec3, color4, float2, etc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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