cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions | Variables
cmnPortability.h File Reference

Portability across compilers and operating systems tools. More...

#include <cisstConfig.h>
#include <cisstCommon/cmnExport.h>
#include <string>
#include <math.h>

Go to the source code of this file.

Macros

#define _cmnPortability_h
 
#define CISST_UNDEFINED   0
 
#define CISST_COMPILER   CISST_UNDEFINED
 
#define CISST_OS   CISST_UNDEFINED
 
#define CISST_OS_IS_WINDOWS   0
 
#define CISST_DATA_MODEL   CISST_UNDEFINED
 
#define CMN_ISNAN(x)   isnan(x)
 Detect a NaN. More...
 
#define CMN_ISFINITE(x)   cmnIsFinite(x)
 
#define CISST_DECLARE_TEMPLATE_FUNCTION_SPECIALIZATION   template<>
 
#define CISST_DEFINE_TEMPLATE_FUNCTION_SPECIALIZATION   template<>
 
#define CMN_UNUSED(argument)   MARKED_AS_UNUSED ## argument
 
#define CMN_DEFAULT_TEMPLATED_CONSTRUCTOR(type)   type()
 Define how to use the constructor of a templated type in a method's signature. More...
 
#define CMN_PRETTY_FUNCTION   ""
 Somewhat portable compilation warning message. This works with very recent versions of gcc (4.5) and with Microsoft compilers. This macro has not been ported to other compilers. More...
 
Testing the operating system
#define CISST_WINDOWS   1
 
#define CISST_LINUX   2
 
#define CISST_RTLINUX   3
 
#define CISST_IRIX   4
 
#define CISST_SOLARIS   5
 
#define CISST_LINUX_RTAI   6
 
#define CISST_CYGWIN   7
 
#define CISST_DARWIN   8
 
#define CISST_QNX   9
 
#define CISST_LINUX_XENOMAI   10
 
Testing the compiler
#define CISST_GCC   1
 
#define CISST_VCPP6   2
 
#define CISST_DOTNET7   3
 
#define CISST_SGI_CC   4
 
#define CISST_SUN_CC   5
 
#define CISST_INTEL_CC   6
 
#define CISST_DOTNET2003   7
 
#define CISST_DOTNET2005   8
 
#define CISST_DOTNET2008   9
 
#define CISST_DOTNET2010   10
 
#define CISST_DOTNET2012   11
 
#define CISST_DOTNET2013   12
 
#define CISST_CLANG   13
 
#define CISST_ILP32   1
 
#define CISST_LP64   2
 
#define CISST_LLP64   3
 
#define CISST_DEPRECATED
 

Functions

bool CISST_EXPORT cmnIsFinite (const float &value)
 Detect a finite number. More...
 
bool CISST_EXPORT cmnIsFinite (const double &value)
 

Variables

CISST_EXPORT const std::string cmnOperatingSystemsStrings []
 
CISST_EXPORT const std::string cmnCompilersStrings []
 

Detailed Description

Portability across compilers and operating systems tools.

Macro Definition Documentation

#define _cmnPortability_h
#define CISST_CLANG   13
#define CISST_COMPILER   CISST_UNDEFINED
#define CISST_CYGWIN   7
#define CISST_DARWIN   8
#define CISST_DATA_MODEL   CISST_UNDEFINED
#define CISST_DECLARE_TEMPLATE_FUNCTION_SPECIALIZATION   template<>

For whatever reason, there is a syntactic incompatiblity between .NET and gcc on the issue of member function template specialization. .NET requires a strict declaration of the specialized member:

template returnType foo::bar<templateArgs>(parameters);

followed by the definition

returnType foo::bar(parameters) { ... }

Whereas gcc can deduce the template arguments by simply looking at the definition

template<> returnType foo::bar(parameters) { ... }

To provide specialization of template functions, we unify these two structures by mandating the explicit declaration preceded by the macro CISST_DECLARE_TEMPLATE_FUNCTION_SPECIALIZATION , then writing the definition preceded by the macro CISST_DEFINE_TEMPLATE_FUNCTION_SPECIALIZATION.

For example:

CISST_DECLARE_TEMPLATE_FUNCTION_SPECIALIZATION void foo::bar<templateArgs>(parameters);

CISST_DEFINE_TEMPLATE_FUNCTION_SPECIALIZATION void foo::bar(parameters) { ... }

#define CISST_DEFINE_TEMPLATE_FUNCTION_SPECIALIZATION   template<>
#define CISST_DEPRECATED

Define the macro CISST_DEPRECATED. In gcc and .NET, a method or other interfaces (e.g., function, and sometimes class, type or variable) can be declared as deprecated by adding specific nonstandard qualifier in the declaration of the object.

We have unified these qualifiers into a single macro. Here's a usage example.

After this declaration, when a programmer uses a call to f() inside any other block, a compiler warning is generated on those compilers which support deprecation qualifiers.

The macro is defined as blank if the compiler does not support deprecation.

Note
More work needs to be done on how to declare a deprecated class
#define CISST_DOTNET2003   7
#define CISST_DOTNET2005   8
#define CISST_DOTNET2008   9
#define CISST_DOTNET2010   10
#define CISST_DOTNET2012   11
#define CISST_DOTNET2013   12
#define CISST_DOTNET7   3
#define CISST_GCC   1

Value used to set the compiler used. To test if the compiler is this one, compare with CISST_COMPILER:

#if (CISST_COMPILER == CISST_GCC)
...
#endif
#define CISST_ILP32   1

Data models for 32 and 64 bits architectures.

#define CISST_INTEL_CC   6
#define CISST_IRIX   4
#define CISST_LINUX   2
#define CISST_LINUX_RTAI   6
#define CISST_LINUX_XENOMAI   10
#define CISST_LLP64   3
#define CISST_LP64   2
#define CISST_OS   CISST_UNDEFINED
#define CISST_OS_IS_WINDOWS   0
#define CISST_QNX   9
#define CISST_RTLINUX   3
#define CISST_SGI_CC   4
#define CISST_SOLARIS   5
#define CISST_SUN_CC   5
#define CISST_UNDEFINED   0

Fallback value for both CISST_OS and CISST_COMPILER.

#define CISST_VCPP6   2
#define CISST_WINDOWS   1

Value used to set the Operating System used. To test if the operating system is this one, compare with CISST_OS:

#if (CISST_OS == CISST_LINUX)
...
#endif
#define CMN_DEFAULT_TEMPLATED_CONSTRUCTOR (   type)    type()

Define how to use the constructor of a templated type in a method's signature.

This macro is required as compilers don't expand the class name (constructor) of a templated type used in a method's signature the same way. For example:

template <class _type>
void myFunction(const _type & arg1, const _type & arg2 = _type()); // for gcc
template <class _type>
void myFunction(const _type & arg1, const _type & arg2 = _type::_type()); // for windows compilers only

The macro should be used as follows:

template <class _type>
void myFunction(const _type & arg1,
const _type & arg2 = CMN_DEFAULT_TEMPLATED_CONSTRUCTOR(_type));
Parameters
typeThe template parameter defining the class constructor to call
#define CMN_ISFINITE (   x)    cmnIsFinite(x)
#define CMN_ISNAN (   x)    isnan(x)

Detect a NaN.

Discard of the Windows.h definition of macros min and max

This macro is a wrapper for different compilers to simplify the use of the NaN macro. With gcc and icc, is uses isnan() and for Microsoft compilers, _isnan(). In most cases, the test should look like:

if (CMN_ISNAN(myValue)) {
... deal with the problem, i.e. not a number;
}
Parameters
xThe number to be tested.
#define CMN_PRETTY_FUNCTION   ""

Somewhat portable compilation warning message. This works with very recent versions of gcc (4.5) and with Microsoft compilers. This macro has not been ported to other compilers.

#define CMN_UNUSED (   argument)    MARKED_AS_UNUSED ## argument

Macro to indicate that a parameter is not used. In some cases, it might be useful to declare a parameter but nevertheless not use it. Some compilers (such as gcc) might issue a warning when this happens (with options -Wall -Wextra). To avoid these warnings, one should use the CMN_UNUSED macro in the method/function declaration:

void FunctionOrMethod(const std::string & CMN_UNUSED(filename) = "default");

This macro should be used only when necessary. Known cases are template specialization, passing an argument to resolve template inference, arguments provided for API consistency with others classes/methods.

Note
This macro is only required where the method is defined. If the declaration and the definition are in two different places (e.g. header file and code file), it is not technically required to use the macro in the header file. Nervertheless, we recommend to use it in both places.

Function Documentation

bool CISST_EXPORT cmnIsFinite ( const float &  value)

Detect a finite number.

This function is a wrapper for different compilers to simplify the use of the finite number macro. With gcc and icc, is uses finite() and for Microsoft compilers, _finite(). In most cases, the test should look like:

if (!cmnIsFinite(myValue)) {
... deal with the problem, i.e. infinite number;
}
Parameters
xThe number to be tested.
bool CISST_EXPORT cmnIsFinite ( const double &  value)

Variable Documentation

CISST_EXPORT const std::string cmnCompilersStrings[]
CISST_EXPORT const std::string cmnOperatingSystemsStrings[]

Disable some specifically annoying warnings printed by Microsoft compilers:

4290 C++ exception specification ignored ... 4251 'identifier' : class 'type' needs to have dll-interface ... 4786 'identifier' : identifier was truncated to 'number' characters ...