ICRS Eurobot 2013

Dependencies:   mbed mbed-rtos Servo QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CommaInitializer.h Source File

CommaInitializer.h

00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: CommaInitializer.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_COMMA_INITIALIZER_H
00025 #define TVMET_COMMA_INITIALIZER_H
00026 
00027 #include <tvmet/CompileTimeError.h>
00028 
00029 namespace tvmet {
00030 
00031 
00032 /**
00033  * \class CommaInitializer CommaInitializer.h "tvmet/CommaInitializer.h"
00034  * \brief Initialize classes using a comma separated lists.
00035  *
00036  * The comma operator is called when it appears next to an object of
00037  * the type the comma is defined for. However, "operator," is not called
00038  * for function argument lists, only for objects that are out in the open,
00039  * separated by commas (Thinking C++
00040  * <a href=http://www.ida.liu.se/~TDDA14/online/v1ticpp/Chapter12.html>
00041  * Ch.12: Operator comma</a>).
00042  *
00043  * This implementation uses the same technique as described in Todd Veldhuizen
00044  * Techniques for Scientific C++
00045  * <a href=http://extreme.indiana.edu/~tveldhui/papers/techniques/techniques01.html#l43>
00046  * chapter 1.11 Comma overloading</a>.
00047  *
00048  * The initializer list is avaible after instanciation of the object,
00049  * therefore use it like:
00050  * \code
00051  * vector3d t;
00052  * t = 1.0, 2.0, 3.0;
00053  * \endcode
00054  * It's evaluated to (((t = 1.0), 2.0), 3.0)
00055  *
00056  * For matrizes the initilization is done row wise.
00057  *
00058  * If the comma separted list of values longer then the size of the vector
00059  * or matrix a compile time error will occour. Otherwise the pending values
00060  * will be written random into the memory.
00061  *
00062  */
00063 template<class Obj, std::size_t LEN>
00064 class CommaInitializer
00065 {
00066   CommaInitializer();
00067   CommaInitializer& operator=(const CommaInitializer&);
00068 
00069 private:
00070   /**
00071    * \class Initializer
00072    * \brief Helper fo recursive overloaded comma operator.
00073    */
00074   template<class T, std::size_t N> class Initializer
00075   {
00076     Initializer();
00077     Initializer& operator=(const Initializer&);
00078 
00079   public:
00080     typedef T                        value_type;
00081     typedef T*                        iterator;
00082 
00083   public:
00084     Initializer(iterator iter) : m_iter(iter) { }
00085 
00086     /** Overloads the comma operator for recursive assign values from comma
00087     separated list. */
00088     Initializer<value_type, N+1> operator,(value_type rhs)
00089     {
00090       TVMET_CT_CONDITION(N < LEN, CommaInitializerList_is_too_long)
00091       *m_iter = rhs;
00092       return Initializer<value_type, N+1>(m_iter + 1);
00093     }
00094 
00095   private:
00096     iterator                         m_iter;
00097   };
00098 
00099 public:
00100   typedef typename Obj::value_type             value_type;
00101   typedef value_type*                    iterator;
00102 
00103 public:
00104   CommaInitializer(const CommaInitializer& rhs)
00105     : m_object(rhs.m_object),
00106       m_data(rhs.m_data),
00107       m_wipeout_on_destruct(true)
00108   {
00109     rhs.disable();
00110   }
00111 
00112   /** Constructor used by Vector or Matrix operator(value_type rhs) */
00113   CommaInitializer(Obj& obj, value_type x)
00114     : m_object(obj),
00115       m_data(x),
00116       m_wipeout_on_destruct(true)
00117   { }
00118 
00119   /** Destructs and assigns the comma separated value. */
00120   ~CommaInitializer() {
00121     if(m_wipeout_on_destruct) m_object.assign_value(m_data);
00122   }
00123 
00124   /** Overloaded comma operator, called only once for the first occoured comma. This
00125       means the first value is assigned by %operator=() and the 2nd value after the
00126       comma. Therfore we call the %Initializer::operator,() for the list starting
00127       after the 2nd. */
00128   Initializer<value_type, 2> operator,(value_type rhs);
00129 
00130   void disable() const { m_wipeout_on_destruct = false; }
00131 
00132 private:
00133   Obj&                             m_object;
00134   value_type                         m_data;
00135   mutable bool                         m_wipeout_on_destruct;
00136 };
00137 
00138 
00139 /*
00140  * Implementation
00141  */
00142 template<class Obj, std::size_t LEN>
00143 typename CommaInitializer<Obj, LEN>::template Initializer<typename Obj::value_type, 2>
00144 CommaInitializer<Obj, LEN>::operator,(typename Obj::value_type rhs)
00145 {
00146   m_wipeout_on_destruct = false;
00147   iterator iter1 = m_object.data();
00148   *iter1         = m_data;
00149   iterator iter2 = iter1 + 1;
00150   *iter2         = rhs;
00151   return Initializer<value_type, 2>(iter2 + 1);
00152 }
00153 
00154 
00155 
00156 } // namespace tvmet
00157 
00158 
00159 #endif //  TVMET_COMMA_INITIALIZER_H
00160 
00161 // Local Variables:
00162 // mode:C++
00163 // tab-width:8
00164 // End: