/* VectorNav HSI Calibration Library v1.0.0.2
 *
 * Copyright (c) 2018 VectorNav Technologies, LLC
 *
 * This source code is proprietary to and copyrighted by VectorNav Technologies, LLC and is
 * available solely under license from VectorNav. All rights reserved. If you do not have a
 * license to use this source code from VectorNav, any use hereof is strictly prohibited by
 * U.S. law and other applicable law. This source code is restricted for use solely with the
 * products of VectorNav and as otherwise set forth in any agreement with VectorNav. Any
 * disclosure of this source code to the public or to any third party is also prohibited.
 */
#ifndef _VN_UTIL_COMPILER_H
#define _VN_UTIL_COMPILER_H

/* This header provides some simple checks for various features supported by the
* current compiler. */

/* Determine the level of standard C support. */
#if __STDC__
  #if defined (__STDC_VERSION__)
    #if (__STDC_VERSION__ >= 199901L)
      #define C99
    #endif
  #endif
#endif

/* Determine if the compiler has stdbool.h. */
#if defined(C99) || _MSC_VER >= 1800
  #define VN_HAVE_STDBOOL_H 1
#else
  #define VN_HAVE_STDBOOL_H 0
#endif

/* Determine if the secure CRT is available. */
#if defined(_MSC_VER)
  #define VN_HAVE_SECURE_CRT 1
#else
  #define VN_HAVE_SECURE_CRT 0
#endif

/* Determine if the generic type math library (tgmath.h) is available. */
#if defined(C99)
  #define VN_HAVE_GENERIC_TYPE_MATH 1
#else
  #define VN_HAVE_GENERIC_TYPE_MATH 0
#endif

#if defined(C99) || defined(_MSC_VER)
  #define VN_HAVE_EXTRA_MATH_FUNCS	1
#else
  #define VN_HAVE_EXTRA_MATH_FUNCS	0
#endif

/* Determines the basic OS system. */
#if defined(_WIN32)
  #define VN_WINDOWS_BASED  1
  #define VN_UNIX_BASED     0
#elif defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__QNXNTO__)
  #define VN_WINDOWS_BASED  0
  #define VN_UNIX_BASED     1
#else
  #error "Unknown System"
#endif

/* CYGWIN is a little different than Unix. */
#if defined(__CYGWIN__)
  #define VN_CYGWIN_BASED   1
#else
  #define VN_CYGWIN_BASED   0
#endif

/* Determine if anonymous unions are allowed. */
#if defined(__STDC_VERSION___) && (__STDC_VERSION__ >= 201112L) && defined(__GNUC__)
  #define VN_ANONYMOUS_UNIONS  1
#elif defined(_MSC_VER) && _MSC_VER >= 1500
  #define VN_ANONYMOUS_UNIONS  1
#else
  #define VN_ANONYMOUS_UNIONS  0
#endif

/* Silences unreferenced parameters. */
#if !defined(lint)
  #if defined(__GNUC__)
    #define VN_UNREFERENCED_PARAMETER(P) ((void)(P))
  #else
    #define VN_UNREFERENCED_PARAMETER(P)  (P)
  #endif
#else
  #define VN_UNREFERENCED_PARAMETER(P) \
    /*lint -save -e527 -e530 */ \
      { \
        (P) = (P); \
      } \
    /*lint -restore */
#endif

/* Determine if we have PRIu64 available for printf. */
#if defined(C99)
  #define VN_HAVE_PRIu64  1
#else
  #define VN_HAVE_PRIu64  0
#endif

/* VN_HAVE_COMPLEX_H indicates if the system provides support for complex numbers.
   NOTE: Visual Studio does not support C99 complex numbers as of VS2017 but beware
         that it may still have complex.h header but is part of the Universal CRT. */
#if defined(__STDC_NO_COMPLEX__)
  /* This compiler does not include the optional complex.h header. */
  #define VN_HAVE_COMPLEX_H   0
#elif defined(__STDC_IEC_559_COMPLEX__) || defined(_Imaginary_I)
  #define VN_HAVE_COMPLEX_H   1
#else
  #define VN_HAVE_COMPLEX_H   0
#endif

#endif
