00001
00002 namespace VectorMagic {
00003 template <int N=1>
00004 struct ComponentPlaceHolder {
00005 };
00006
00007 struct InsertionStyle {};
00008 struct CommaStyle {};
00009
00010
00011 template<bool Good> struct sentinel
00012 {
00013 typedef int too_many_elements_inserted;
00014 };
00015
00016 template<> struct sentinel<false>
00017 {
00018 };
00019
00020 template <int Index, int Limit, class Vec, class Style> struct VectorFiller;
00021 template <int Index, int Limit, class Vec> struct VectorFiller<Index,Limit,Vec,CommaStyle> {
00022
00023
00024
00025 typedef typename sentinel<(Limit >= Index)>::too_many_elements_inserted dummy;
00026
00027 Vec& v;
00028 bool final_initializer_but_Vector_not_filled;
00029 inline VectorFiller(Vec& vec) : v(vec), final_initializer_but_Vector_not_filled(Index!=Limit) {}
00030
00031 inline VectorFiller<Index+1,Limit,Vec,CommaStyle> operator,(double t) {
00032 v[Index] = t;
00033 final_initializer_but_Vector_not_filled = false;
00034 return VectorFiller<Index+1,Limit,Vec,CommaStyle>(v);
00035 }
00036 template <int N> inline VectorFiller<Index+N,Limit,Vec,CommaStyle> operator,(const ComponentPlaceHolder<N>& ph) {
00037 final_initializer_but_Vector_not_filled = false;
00038 return (VectorFiller<Index+1,Limit,Vec,CommaStyle>(v), ComponentPlaceHolder<N-1>());
00039 }
00040 inline VectorFiller<Index+1,Limit,Vec,CommaStyle> operator,(const ComponentPlaceHolder<1>& ph) {
00041 final_initializer_but_Vector_not_filled = false;
00042 return VectorFiller<Index+1,Limit,Vec,CommaStyle>(v);
00043 }
00044 inline ~VectorFiller() {
00045 assert(!final_initializer_but_Vector_not_filled);
00046 }
00047 inline operator Vec () const { return v; }
00048 };
00049
00050 template <int Index, int Limit, class Vec> struct VectorFiller<Index,Limit,Vec,InsertionStyle> {
00051 typedef typename sentinel<(Limit >= Index)>::too_many_elements_inserted dummy;
00052 Vec& v;
00053 inline VectorFiller(Vec& vec) : v(vec){}
00054
00055 template <int N> inline VectorFiller<Index+N,Limit,Vec,InsertionStyle> operator<<(const Vector<N>& t) {
00056 v.template slice<Index,N>() = t;
00057 return VectorFiller<Index+N,Limit,Vec,InsertionStyle>(v);
00058 }
00059
00060 inline VectorFiller<Index+1,Limit,Vec,InsertionStyle> operator<<(double t) {
00061 v[Index] = t;
00062 return VectorFiller<Index+1,Limit,Vec,InsertionStyle>(v);
00063 }
00064 template <int N> inline VectorFiller<Index+N,Limit,Vec,InsertionStyle> operator<<(const ComponentPlaceHolder<N>& ph) {
00065 return (VectorFiller<Index+1,Limit,Vec,InsertionStyle>(v) << ComponentPlaceHolder<N-1>());
00066 }
00067 inline VectorFiller<Index+1,Limit,Vec,InsertionStyle> operator<<(const ComponentPlaceHolder<1>& ph) {
00068 return VectorFiller<Index+1,Limit,Vec,InsertionStyle>(v);
00069 }
00070 inline operator Vec () const { return v; }
00071 };
00072
00073
00074 template <class Left, int Size> struct VectorCreator
00075 {
00076 const Left& left;
00077 double val;
00078 VectorCreator(const Left& l, double v) : left(l), val(v) { }
00079 VectorCreator<VectorCreator<Left,Size>, Size+1> operator,(double t) const {
00080 return VectorCreator<VectorCreator<Left,Size>, Size+1>(*this, t);
00081 }
00082 template <class V> void assign(V& v) const { v[Size-1] = val; left.assign(v); }
00083 operator Vector<Size> () const {
00084 Vector<Size> v;
00085 assign(v);
00086 return v;
00087 }
00088 };
00089
00090 struct BaseVectorCreator
00091 {
00092 inline VectorCreator<BaseVectorCreator, 1> operator,(double t) const {
00093 return VectorCreator<BaseVectorCreator, 1>(*this, t);
00094 }
00095 template <class V> inline void assign(V& ) const {}
00096 };
00097 }
00098
00099 static VectorMagic::BaseVectorCreator make_Vector;
00100
00101 namespace VectorMagic
00102 {
00103 inline void dummy_make_Vector_user() { int i; make_Vector.assign(i); }
00104 }
00105
00106 template <int N> VectorMagic::ComponentPlaceHolder<N> no_change() { return VectorMagic::ComponentPlaceHolder<N>(); }
00107 inline VectorMagic::ComponentPlaceHolder<1> no_change() { return VectorMagic::ComponentPlaceHolder<1>(); }