Oskar Weigl
/
Eurobot2013
We are going to win! wohoo
tvmet/CommaInitializer.h
- Committer:
- madcowswe
- Date:
- 2012-11-14
- Revision:
- 9:08552997b544
- Parent:
- 1:6799c07fe510
File content as of revision 9:08552997b544:
/* * Tiny Vector Matrix Library * Dense Vector Matrix Libary of Tiny size using Expression Templates * * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: CommaInitializer.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $ */ #ifndef TVMET_COMMA_INITIALIZER_H #define TVMET_COMMA_INITIALIZER_H #include <tvmet/CompileTimeError.h> namespace tvmet { /** * \class CommaInitializer CommaInitializer.h "tvmet/CommaInitializer.h" * \brief Initialize classes using a comma separated lists. * * The comma operator is called when it appears next to an object of * the type the comma is defined for. However, "operator," is not called * for function argument lists, only for objects that are out in the open, * separated by commas (Thinking C++ * <a href=http://www.ida.liu.se/~TDDA14/online/v1ticpp/Chapter12.html> * Ch.12: Operator comma</a>). * * This implementation uses the same technique as described in Todd Veldhuizen * Techniques for Scientific C++ * <a href=http://extreme.indiana.edu/~tveldhui/papers/techniques/techniques01.html#l43> * chapter 1.11 Comma overloading</a>. * * The initializer list is avaible after instanciation of the object, * therefore use it like: * \code * vector3d t; * t = 1.0, 2.0, 3.0; * \endcode * It's evaluated to (((t = 1.0), 2.0), 3.0) * * For matrizes the initilization is done row wise. * * If the comma separted list of values longer then the size of the vector * or matrix a compile time error will occour. Otherwise the pending values * will be written random into the memory. * */ template<class Obj, std::size_t LEN> class CommaInitializer { CommaInitializer(); CommaInitializer& operator=(const CommaInitializer&); private: /** * \class Initializer * \brief Helper fo recursive overloaded comma operator. */ template<class T, std::size_t N> class Initializer { Initializer(); Initializer& operator=(const Initializer&); public: typedef T value_type; typedef T* iterator; public: Initializer(iterator iter) : m_iter(iter) { } /** Overloads the comma operator for recursive assign values from comma separated list. */ Initializer<value_type, N+1> operator,(value_type rhs) { TVMET_CT_CONDITION(N < LEN, CommaInitializerList_is_too_long) *m_iter = rhs; return Initializer<value_type, N+1>(m_iter + 1); } private: iterator m_iter; }; public: typedef typename Obj::value_type value_type; typedef value_type* iterator; public: CommaInitializer(const CommaInitializer& rhs) : m_object(rhs.m_object), m_data(rhs.m_data), m_wipeout_on_destruct(true) { rhs.disable(); } /** Constructor used by Vector or Matrix operator(value_type rhs) */ CommaInitializer(Obj& obj, value_type x) : m_object(obj), m_data(x), m_wipeout_on_destruct(true) { } /** Destructs and assigns the comma separated value. */ ~CommaInitializer() { if(m_wipeout_on_destruct) m_object.assign_value(m_data); } /** Overloaded comma operator, called only once for the first occoured comma. This means the first value is assigned by %operator=() and the 2nd value after the comma. Therfore we call the %Initializer::operator,() for the list starting after the 2nd. */ Initializer<value_type, 2> operator,(value_type rhs); void disable() const { m_wipeout_on_destruct = false; } private: Obj& m_object; value_type m_data; mutable bool m_wipeout_on_destruct; }; /* * Implementation */ template<class Obj, std::size_t LEN> typename CommaInitializer<Obj, LEN>::template Initializer<typename Obj::value_type, 2> CommaInitializer<Obj, LEN>::operator,(typename Obj::value_type rhs) { m_wipeout_on_destruct = false; iterator iter1 = m_object.data(); *iter1 = m_data; iterator iter2 = iter1 + 1; *iter2 = rhs; return Initializer<value_type, 2>(iter2 + 1); } } // namespace tvmet #endif // TVMET_COMMA_INITIALIZER_H // Local Variables: // mode:C++ // tab-width:8 // End: