// ADH_port.h (c) 2005 adolfo@di-mare.com /** \file ADH_port.h \brief Encabezado para que los programas puedan ser compilados con varios compiladores Este archivo de encabezado permite compilar los programas de \c adolfo@di-mare.com usando cualquiera de estos compiladores: - Microsoft C++ .NET - Microsoft C++ v6 - Borland C++ v3.1 \par Uso de \c "namespace" Para permitir que el código sea compilador con el Borland C++ v3.1, que no permite usar \c "namespace", los programas están escritos usando estas macros, que sirven para iniciar, usar y terminar un \c "namespace": - OPEN_namespace(N) // namespace N { - USING_namespace(N) // using namespace N - CLOSE_namespace(N) // } // namespace N \par Omitir las definiciones de \c "namespace" Si por alguna razón conviene omitir todas las definiciones de \c "namespace" basta declarar la macro \c NO_namespace antes de incluir este archivo de encabezado: - #define NO_namespace - #include <ADH_port.h> El efecto de usar \c NO_namespace es que, efectivamente, las 3 macros quedarían definidas así: - OPEN_namespace(N) // no abre namespace N - USING_namespace(N // no usa namespace N - CLOSE_namespace(N) // no cierra namespace N \par Uso de \c "#include" El compilador C++ de Visual Studio .NET usa nombres de archivos de encabezado que no tienen el sufijo \c ".h". Por ejemplo, para usar un flujo de entrada, el programador debe incluir estas líneas: - MSC++ v6 ====> # include <iostream.h> // con \c ".h" - MSC++ .NET ==> # include <iostream> // SIN \c ".h" Para incluir el archivo de encabezado correcto es necesario establecer cuál compilador se está usando. Para evitar usar varias directivas # ifdef, se puede definir una macro que indica cuál archivos de encabezado incluir. No todos los encabezados estándar están incorporados aquí, pero sí los más usados. Por ejemplo, para usar el archivo de encabadezdos \c <iostream> basta incluir en el código fuente la definición de este macro: - \c # define INCLUDE_iostream \par Diferencias entre MSC++ v6 y MSC++ .NET Lo usual es encontrar código escrito para la versión vieja del compilador de Microsoft, el MSC++ v6.0 o anterior. Con frecuencia, basta hacer estas modificaciones para que el código pueda ser compilador con MSC++ .NET: - Agregar el renglón using namespace std;
- Eliminar el \c ".h" de los encabezados estándar [por ejemplo, cambiar <iostream.h> por <iostream>] - En muchos casos, es necesario eliminar el \c ".h" cuando se usan archivos de encabezado de la biblioteca estándar C [por ejemplo, cambiar <stdlib.h> por <cstdlib>] - En otros casos, es necesario usar el nombre antiguo del archivo de encabezado [por ejemplo, sí sirve <math.h> pero no sirve <cmath>] \par Borland C++ v3.1 En algunas ocasiones conviene más usar el compilador BC++ v3.1 porque es un compilador que requiere muy pocos recursos traducir programas.Desafortundamente, el BC++ v3.1 tiene varias restricciones de funcionamiento entre las que se destacan éstas: - No tiene definido el tipo \c "bool" - No permite usar \c "namespace" - No permite usar excepciones - No usa correctamente las reglas de conversi¢n de tipos Algunos ejemplos C++ son sólo puedes ser expresado correctamente usando el lenguaje C++ moderno, est ndar. Pero muchos otros no requieren tanta expresividad por lo que pueden ser compilados con BC++ v3.1. Para lograrlo es necesario usar. \par Ejemplo de uso \code #ifndef String_h #define String_h // Evita la inclusión múltiple #define INCLUDE_iostream // ==> # include #include "ADH_port.h" OPEN_namespace(ADH) USING_namespace(std); // es necesario agregar el punto y coma class String{ // ... }; CLOSE_namespace(ADH) USING_namespace(ADH); // es necesario agregar el ";" ADH::String& operator<<( std::ostream COUT&; ADH::String& s); #endif // String_h \endcode \par Resultado en Borland C++ v3.1 \code #ifndef String_h #define String_h // Evita la inclusión múltiple #include #include "ADH_port.h" // namespace ADH { // ==> eliminado ; // using namespace std // ==> eliminado class String{ // ... }; // } ==> eliminado // using namespace ADH; // ==> eliminado // ADH && std ==> eliminado ::String& operator<<( ::ostream COUT&; ::String& s); #endif // String_h \endcode \par Resultado en Microsft C++ .NET \code #ifndef String_h #define String_h // Evita la inclusión múltiple #include // sin ".h" #include "ADH_port.h" using namespace std; // Agregado en "ADH_port.h" namespace ADH { using namespace std; class String{ // ... }; } // namespace ADH using namespace ADH; ADH::String& operator<<( std::ostream COUT&; ADH::String& s); #endif // String_h \endcode \author Adolfo Di Mare \date 2005 */ #ifndef ADH_port_h #define ADH_port_h ///< Evita la inclusión múltiple // Documentados acá para Doxygen #undef CLOSE_namespace #undef USING_namespace #undef OPEN_namespace /// Abre namespace \c "N" #define OPEN_namespace(N) namespace N { /// Cierra namespace \c "N" #define CLOSE_namespace(N) } /// Usa namespace \c "N" #define USING_namespace(N) using namespace N // Los anula para luego definirlos dentro del #ifdef correcto #undef CLOSE_namespace #undef USING_namespace #undef OPEN_namespace #ifdef DOXYGEN_COMMENT // Documentados acá para Doxygen /// Definido por la biblioteca C++ estándar namespace std {} // Está acá para que Doxygen lo documente /// ADH son las siglas de \c adolfo@di-mare.com namespace ADH {} // Está acá para que Doxygen lo documente #define INCLUDE_fstream Truco para "#include " portable #define INCLUDE_iomanip Truco para "#include " portable #define INCLUDE_iostream Truco para "#include " portable #define INCLUDE_list Truco para "#include " portable #define INCLUDE_map Truco para "#include " portable #define INCLUDE_stdexcept Truco para "#include " portable #define INCLUDE_vector Truco para "#include " portable #endif // Borland C++ #ifdef __BORLANDC__ ///< Definida para Borland C++ #if (__BORLANDC__ <= 0x0410) // Identifica a BC++ v3.1 y anterior // Declara el tipo "bool" porque BC++ v3.1 NO tiene "bool" #ifndef _bool_h #define _bool_h #undef false #undef true #undef bool typedef int bool; const int false = 0; const int true = ! false; // BC++ v3.1 NO tiene "bool" #endif class istream; class ostream; #define using // BC++ v3.1 NO tiene "namespace" #define namespace #define std #define ADH #define OPEN_namespace(N) // BC++ v3.1 NO tiene "namespace" #define CLOSE_namespace(N) #define USING_namespace(N) #ifdef INCLUDE_fstream #include #endif #ifdef INCLUDE_iomanip #include #endif #ifdef INCLUDE_iostream #include #endif #ifdef INCLUDE_list #include #endif #ifdef INCLUDE_map #include #endif #ifdef INCLUDE_set #include #endif #ifdef INCLUDE_stdexcept #include #endif #ifdef INCLUDE_string #include #endif #ifdef INCLUDE_vector #include #endif #endif #if (__BORLANDC__ > 0x0410) // Versiones posteriores a BC++ v3.1 #define OPEN_namespace(N) namespace N { #define CLOSE_namespace(N) } #define USING_namespace(N) using namespace N #error Ajuste ADH_port.h para compìlar con versiones nuevas de BC++ #endif #endif // Microsoft C++ (Visual Studio) #ifdef _MSC_VER ///< Definida para Micrsoft C++ // namespace #define OPEN_namespace(N) namespace N { #define CLOSE_namespace(N) } #define USING_namespace(N) using namespace N #if (_MSC_VER >= 1300) // Identifica a VC++ .net /// Definido por la biblioteca C++ estándar namespace std {} // Está acá para que Doxygen lo documente // using namespace std; #ifdef INCLUDE_fstream #include #endif #ifdef INCLUDE_iomanip #include #endif #ifdef INCLUDE_iostream #include #endif #ifdef INCLUDE_list #include #endif #ifdef INCLUDE_map #include #endif #ifdef INCLUDE_set #include #endif #ifdef INCLUDE_stdexcept #include #endif #ifdef INCLUDE_string #include #endif #ifdef INCLUDE_vector #include #endif #endif #if (_MSC_VER < 1300) // Identifica a VC++ v6 y anterior namespace std {} // Está acá para que Doxygen lo documente // using namespace std; // Antes de MSC++ .NET hay que usar <.h> #ifdef INCLUDE_fstream #include #endif #ifdef INCLUDE_iomanip #include #endif #ifdef INCLUDE_iostream #include #endif #ifdef INCLUDE_list #include #endif #ifdef INCLUDE_map #include #endif #ifdef INCLUDE_set #include #endif #ifdef INCLUDE_stdexcept #include #endif #ifdef INCLUDE_string #include #endif #ifdef INCLUDE_vector #include #endif #endif #endif #ifdef __GNUC__ ///< Definida para GNU C++ // namespace #define OPEN_namespace(N) namespace N { #define CLOSE_namespace(N) } #define USING_namespace(N) using namespace N namespace std {} // Está acá para que Doxygen lo documente // using namespace std; #ifdef INCLUDE_fstream #include #endif #ifdef INCLUDE_iomanip #include #endif #ifdef INCLUDE_iostream #include #endif #ifdef INCLUDE_list #include #endif #ifdef INCLUDE_map #include #endif #ifdef INCLUDE_set #include #endif #ifdef INCLUDE_stdexcept #include #endif #ifdef INCLUDE_string #include #endif #ifdef INCLUDE_vector #include #endif #endif #ifdef NO_namespace ///< Omita las definiciones de \c "namespace" #undef CLOSE_namespace #undef USING_namespace #undef OPEN_namespace #define CLOSE_namespace(N) // no cierra namespace N #define USING_namespace(N) // no usa namespace N #define OPEN_namespace(N) // no abre namespace N #endif #endif // ADH_port_h // EOF: ADH_port.h