Updated license
[anna.git] / include / anna / core / util / CommaSeparatedList.hpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_core_util_CommaSeparatedList_hpp
38 #define anna_core_util_CommaSeparatedList_hpp
39
40 namespace anna {
41
42 /**
43    Obtiene una lista de objetos a partir de la lista expresada con el operador ','.
44    Lo mas normal es que sea usada para pasar un numero indeterminado de parametros del mismo tipo a un metodo
45    o funcion.
46
47    Por ejemplo el modo de uso seria el siguiente:
48
49    \code
50       CommaSeparatedList <Objeto> params;
51       Objeto a, b, c;
52
53       params = a, b, c;
54
55       for (CommaSeparatedList<Objeto>::const_iterator ii = params.begin (), maxii = params.end (); ii != maxii; ii ++) {
56          Objecto* obj = CommaSeparatedList<Objeto>::data (ii);
57
58          .... usa el objeto de la lista ...
59       }
60
61    \endcode
62
63    Un ejemplo mas realista. Suponed que tenemos una funcion que tiene que recibir un numero indeterminado
64    de instancia de tipo Objeto. Se definira de la forma:
65
66    \code
67    void cualquierFuncion (const anna::CommaSeparatedList <Objeto>& csl) {
68       for (CommaSeparatedList<Objeto>::const_iterator ii = params.begin (), maxii = params.end (); ii != maxii; ii ++) {
69          Objecto* obj = CommaSeparatedList<Objeto>::data (ii);
70
71          .... usa el objeto de la lista ...
72       }
73    }
74    \endcode
75
76    La invocacion a la funcion sera:
77
78    \code
79    Objeto aaa, bbb, ccc;
80
81    cualquierFunction (aaa, bbb, ccc);
82    cualquierFunction (bbb, ccc);
83
84    \endcode
85
86    En el primer caso la lista de objetos terminara conteniendo los elementos aaa, bbb y ccc..
87    En el segundo caso la lista de objetos terminara conteniendo los elementos bbb y ccc.
88 */
89 template <typename T> class CommaSeparatedList {
90 public:
91   typedef typename std::vector <T*>::iterator iterator; /**< Definicion para recorrer los elementos. */
92   typedef typename std::vector <T*>::const_iterator const_iterator; /**< Definicion para recorrer los elementos */
93
94   /**
95      Constructor vacio.
96   */
97   CommaSeparatedList() {;}
98
99   /**
100      Destructor.
101   */
102   ~CommaSeparatedList() { a_parameters.clear(); }
103
104   /**
105      Operador coma re-escrito para recorrer los objetos de la expresion basada en ','.
106      Cada uno de los elementos de la expresion es convertido a un elemento de la lista.
107      \param t Parametro con el que ampliar la lista.
108      \return La instancia de la lista destino.
109   */
110   CommaSeparatedList<T>& operator, (T& t) throw() { a_parameters.push_back(&t); return *this; }
111
112   /**
113      Operador de asignacion.
114      Amplia la lista con el elemento recibido.
115      \param t Parametro con el que ampliar la lista.
116      \return La instancia de la lista destino.
117   */
118   CommaSeparatedList<T>& operator= (T& t) throw() { a_parameters.push_back(&t); return *this; }
119
120   /**
121      Operador de copia.
122      \param rsh Lista de parametros a copiar.
123      \return La instancia de la lista destino.
124   */
125   CommaSeparatedList<T>& operator= (CommaSeparatedList<T>& rsh) throw() {
126     if(this != &rsh)
127       a_parameters = rsh.parameters;
128
129     return *this;
130   }
131
132   /**
133      Elimina el contenido actual de la lista de parametros.
134   */
135   void clear() throw() { a_parameters.clear(); }
136
137   /**
138      Devuelve un iterator al primer parametro de la lista.
139      \return Un iterator al primer parametro de la lista.
140   */
141   iterator begin() throw() { return a_parameters.begin(); }
142
143   /**
144      Devuelve un iterator al primer parametro de la lista.
145      \return Un iterator al primer parametro de la lista.
146   */
147   const_iterator begin() const throw() { return a_parameters.begin(); }
148
149   /**
150      Devuelve un iterator al ultimo parametro de la lista.
151      \return Un iterator al ultimo parametro de la lista.
152   */
153   iterator end() throw() { return a_parameters.end(); }
154
155   /**
156      Devuelve un iterator al ultimo parametro de la lista.
157      \return Un iterator al ultimo parametro de la lista.
158   */
159   const_iterator end() const throw() { return a_parameters.end(); }
160
161   /**
162      Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
163      \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
164   */
165   static T* data(iterator& ii) throw() { return *ii; }
166
167   /**
168      Devuelve el puntero sobre el que esta posicionado el iterador recibido como parametro.
169      \return El puntero sobre el que esta posicionado el iterador recibido como parametro.
170   */
171   static const T* data(const_iterator& ii) throw() { return *ii; }
172
173 private:
174   std::vector <T*> a_parameters;
175 };
176
177 }
178
179 #endif
180