1 /* 2 * Tiny Vector Matrix Library 3 * Dense Vector Matrix Libary of Tiny size using Expression Templates 4 * 5 * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 * $Id: CommaInitializer.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $ 22 */ 23 24 #ifndef TVMET_COMMA_INITIALIZER_H 25 #define TVMET_COMMA_INITIALIZER_H 26 27 #include <tvmet/CompileTimeError.h> 28 29 namespace tvmet { 30 31 32 /** 33 * \class CommaInitializer CommaInitializer.h "tvmet/CommaInitializer.h" 34 * \brief Initialize classes using a comma separated lists. 35 * 36 * The comma operator is called when it appears next to an object of 37 * the type the comma is defined for. However, "operator," is not called 38 * for function argument lists, only for objects that are out in the open, 39 * separated by commas (Thinking C++ 40 * <a href=http://www.ida.liu.se/~TDDA14/online/v1ticpp/Chapter12.html> 41 * Ch.12: Operator comma</a>). 42 * 43 * This implementation uses the same technique as described in Todd Veldhuizen 44 * Techniques for Scientific C++ 45 * <a href=http://extreme.indiana.edu/~tveldhui/papers/techniques/techniques01.html#l43> 46 * chapter 1.11 Comma overloading</a>. 47 * 48 * The initializer list is avaible after instanciation of the object, 49 * therefore use it like: 50 * \code 51 * vector3d t; 52 * t = 1.0, 2.0, 3.0; 53 * \endcode 54 * It's evaluated to (((t = 1.0), 2.0), 3.0) 55 * 56 * For matrizes the initilization is done row wise. 57 * 58 * If the comma separted list of values longer then the size of the vector 59 * or matrix a compile time error will occour. Otherwise the pending values 60 * will be written random into the memory. 61 * 62 */ 63 template<class Obj, std::size_t LEN> 64 class CommaInitializer 65 { 66 CommaInitializer(); 67 CommaInitializer& operator=(const CommaInitializer&); 68 69 private: 70 /** 71 * \class Initializer 72 * \brief Helper fo recursive overloaded comma operator. 73 */ 74 template<class T, std::size_t N> class Initializer 75 { 76 Initializer(); 77 Initializer& operator=(const Initializer&); 78 79 public: 80 typedef T value_type; 81 typedef T* iterator; 82 83 public: Initializer(iterator iter)84 Initializer(iterator iter) : m_iter(iter) { } 85 86 /** Overloads the comma operator for recursive assign values from comma 87 separated list. */ 88 Initializer<value_type, N+1> operator,(value_type rhs) 89 { 90 TVMET_CT_CONDITION(N < LEN, CommaInitializerList_is_too_long) 91 *m_iter = rhs; 92 return Initializer<value_type, N+1>(m_iter + 1); 93 } 94 95 private: 96 iterator m_iter; 97 }; 98 99 public: 100 typedef typename Obj::value_type value_type; 101 typedef value_type* iterator; 102 103 public: CommaInitializer(const CommaInitializer & rhs)104 CommaInitializer(const CommaInitializer& rhs) 105 : m_object(rhs.m_object), 106 m_data(rhs.m_data), 107 m_wipeout_on_destruct(true) 108 { 109 rhs.disable(); 110 } 111 112 /** Constructor used by Vector or Matrix operator(value_type rhs) */ CommaInitializer(Obj & obj,value_type x)113 CommaInitializer(Obj& obj, value_type x) 114 : m_object(obj), 115 m_data(x), 116 m_wipeout_on_destruct(true) 117 { } 118 119 /** Destructs and assigns the comma separated value. */ ~CommaInitializer()120 ~CommaInitializer() { 121 if(m_wipeout_on_destruct) m_object.assign_value(m_data); 122 } 123 124 /** Overloaded comma operator, called only once for the first occoured comma. This 125 means the first value is assigned by %operator=() and the 2nd value after the 126 comma. Therfore we call the %Initializer::operator,() for the list starting 127 after the 2nd. */ 128 Initializer<value_type, 2> operator,(value_type rhs); 129 disable()130 void disable() const { m_wipeout_on_destruct = false; } 131 132 private: 133 Obj& m_object; 134 value_type m_data; 135 mutable bool m_wipeout_on_destruct; 136 }; 137 138 139 /* 140 * Implementation 141 */ 142 template<class Obj, std::size_t LEN> 143 typename CommaInitializer<Obj, LEN>::template Initializer<typename Obj::value_type, 2> 144 CommaInitializer<Obj, LEN>::operator,(typename Obj::value_type rhs) 145 { 146 m_wipeout_on_destruct = false; 147 iterator iter1 = m_object.data(); 148 *iter1 = m_data; 149 iterator iter2 = iter1 + 1; 150 *iter2 = rhs; 151 return Initializer<value_type, 2>(iter2 + 1); 152 } 153 154 155 156 } // namespace tvmet 157 158 159 #endif // TVMET_COMMA_INITIALIZER_H 160 161 // Local Variables: 162 // mode:C++ 163 // tab-width:8 164 // End: 165