1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
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
17 // * Neither the name of the copyright holder 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.
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.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_core_define_autoenum_hpp
38 #define anna_core_define_autoenum_hpp
42 #include <anna/core/RuntimeException.hpp>
47 * Facilita la declaración de enumerados y sus correspondientes métodos de conversión.
48 * Los valores de los enumerados debe incluir el valor \em None, que será usado en el método
49 * asEnum (const char*) incorporado por esta macro en caso de no encontrar ninguna correspondencia.
51 * El numerado desde el que se invoque esta macro incluirá de forma automática los siguiente métodos:
53 * \li _v Transport::asEnum (const char* str): que compara la cadena recibida con las cadenas establecidas al asignar los valores
54 * literales del enumerado y devuelve su valor enumerado. Si no hay coincidencia devolverá None.
55 * \li _v Transport::asEnum (const std::string& str): que compara la cadena recibida con las cadenas establecidas al asignar los valores
56 * literales del enumerado y devuelve su valor enumerado. Si no hay coincidencia devolverá None.
57 * \li _v Transport::asEnumEx (const char* str): que compara la cadena recibida con las cadenas establecidas al asignar los valores
58 * literales del enumerado y devuelve su valor enumerado. Si no hay coincidencia lanzará una excepción.
59 * \li _v Transport::asEnumEx (const std::string& str): que compara la cadena recibida con las cadenas establecidas al asignar los valores
60 * literales del enumerado y devuelve su valor enumerado. Si no hay coincidencia lanzará una excepción.
61 * \li const char* asCString (const _v) que devuelve el literal asociado al valor del enumerado recibido como parámetro. Puede devolver NULL.
62 * \li const char* asNotNullCString (const _v) que devuelve el literal asociado al valor del enumerado recibido como parámetro. Puede devolver "<none>".
63 * \li std::string asList () que devuelve el literal que la lista de valores válidos.
65 * Así quedaría la declaración del enumerado, que normalmente estará en un .h
68 * enum _v { None = -1, TCP, SCTP, UDP };
69 * anna_declare_enum (Transport);
76 #define anna_declare_enum(name) \
77 static const char* literal []; \
78 static _v asEnum (const char* str) throw () { \
79 for (int ii = 0; literal [ii] != NULL; ii ++) { \
80 if (strcasecmp (str, literal [ii]) == 0) \
85 static _v asEnumEx (const char* str) throw (anna::RuntimeException) { \
87 std::string msg (#name); \
88 msg += "::asEnumEx | str can not be null"; \
89 throw anna::RuntimeException (msg, __FILE__,__LINE__); \
91 _v result = asEnum (str); \
92 if (result == None) { \
93 std::string msg (#name); \
94 msg += " | Value: '"; \
96 msg += "' is not valid | Valid values: "; \
98 throw anna::RuntimeException (msg, __FILE__, __LINE__); \
102 static _v asEnum (const std::string& str) throw () { return asEnum (str.c_str ()); } \
103 static _v asEnumEx (const std::string& str) throw (anna::RuntimeException) { return asEnumEx (str.c_str ()); } \
104 static const char* asCString (const _v v) throw () { return (v != None) ? literal [v]: NULL; } \
105 static const char* asNotNullCString (const _v v) throw () { return (v != None) ? literal [v]: "<none>"; } \
106 static std::string asList () throw () {\
108 for (int ii = 0; literal [ii] != NULL; ii ++) { \
109 if (ii == 0 && strcmp (literal [ii], "None") == 0) continue; \
110 if (ii > 1) result += ' '; \
111 result += "'"; result += literal [ii]; result += "'"; \
119 * Establece los literales asociados a cada uno de los valores de la enumeración.
121 * Hay que completar el enumerado asignando los literales asociados a cada uno de los valores:
124 * anna_assign_enum (diameter::avp::DiameterURI::Transport) = { "tcp", "sctp", "udp", NULL };
128 * \warning Debe incluir el valor \em NULL para indicar el fin de la lista de valores.
130 #define anna_assign_enum(name) const char* name::literal []
134 * Accede al literal definido por el Enumado y la posicion indicada como parámetro
136 #define anna_item_enum(name,ii) name::literal[ii]