/*
 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef YARP_CONF_API_H
#define YARP_CONF_API_H

#include <yarp/conf/compiler.h>
#include <yarp/conf/system.h>

/*

The purpose of this header file is to correctly define:
  YARP_EXPORT
  YARP_IMPORT
Since YARP is composed of several libraries, we may be compiling one
library (and exporting its symbols) while using another (and importing
its symbols).  The set of YARP libraries is rather open-ended so,
it is better not to try enumerating them here.  Given that, the
recommended usage of this header within YARP is:
//
#include <yarp/conf/api.h>
#ifndef YARP_os_API
#  ifdef YARP_os_EXPORTS
#    define YARP_os_API YARP_EXPORT
#    define YARP_os_EXTERN YARP_EXPORT_EXTERN
#  else
#    define YARP_os_API YARP_IMPORT
#    define YARP_os_EXTERN YARP_IMPORT_EXTERN
#  endif
#  define YARP_os_DEPRECATED_API YARP_DEPRECATED_API
#  define YARP_os_DEPRECATED_API_MSG(X) YARP_DEPRECATED_API_MSG(X)
#endif

(replace YARP_os with CMake target name for library)

*/

// Defined if YARP is compiled as a shared library
#define YARP_DLL

// Defined if YARP is configured to apply filter out the implementation library
// from the ABI
/* #undef YARP_FILTER_impl */

#if defined _WIN32 || defined __CYGWIN__
#  define YARP_HELPER_DLL_IMPORT __declspec(dllimport)
#  define YARP_HELPER_DLL_EXPORT __declspec(dllexport)
#  define YARP_HELPER_DLL_LOCAL
#  define YARP_HELPER_DLL_IMPORT_EXTERN YARP_EXTERN_TEMPLATE
#  define YARP_HELPER_DLL_EXPORT_EXTERN
#elif (YARP_COMPILER_IS_GNU && (__GNUC__ >= 4)) || YARP_COMPILER_IS_Clang || YARP_COMPILER_IS_AppleClang
#  define YARP_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
#  define YARP_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
#  define YARP_HELPER_DLL_LOCAL  __attribute__ ((visibility ("hidden")))
#  define YARP_HELPER_DLL_IMPORT_EXTERN YARP_EXTERN_TEMPLATE
#  define YARP_HELPER_DLL_EXPORT_EXTERN YARP_EXTERN_TEMPLATE
#else
#  define YARP_HELPER_DLL_IMPORT
#  define YARP_HELPER_DLL_EXPORT
#  define YARP_HELPER_DLL_LOCAL
#  define YARP_HELPER_DLL_IMPORT_EXTERN YARP_EXTERN_TEMPLATE
#  define YARP_HELPER_DLL_EXPORT_EXTERN YARP_EXTERN_TEMPLATE
#endif

#if defined YARP_DLL
#  define YARP_IMPORT YARP_HELPER_DLL_IMPORT
#  define YARP_EXPORT YARP_HELPER_DLL_EXPORT
#  define YARP_LOCAL YARP_HELPER_DLL_LOCAL
#  define YARP_IMPORT_EXTERN YARP_HELPER_DLL_IMPORT_EXTERN
#  define YARP_EXPORT_EXTERN YARP_HELPER_DLL_EXPORT_EXTERN
#else
#  define YARP_IMPORT
#  define YARP_EXPORT
#  define YARP_LOCAL
#  define YARP_IMPORT_EXTERN YARP_EXTERN_TEMPLATE
#  define YARP_EXPORT_EXTERN YARP_EXTERN_TEMPLATE
#endif

// YARP_DEPRECATED and YARP_DEPRECATED_MSG are defined in compiler.h, but we
// want warnings disabled if YARP_NO_DEPRECATED_WARNINGS is enabled
#if defined YARP_NO_DEPRECATED_WARNINGS
#  undef YARP_DEPRECATED
#  undef YARP_DEPRECATED_MSG
#endif
// If YARP_DEPRECATED and YARP_DEPRECATED_MSG are undefined, define them empty
#ifndef YARP_DEPRECATED
#  define YARP_DEPRECATED
#  define YARP_DEPRECATED_MSG(X)
#endif


// Position for the attribute [[deprecated]] for typedef is different compared
// to compiler-specific attributes
#if defined(YARP_COMPILER_CXX_ATTRIBUTE_DEPRECATED) && YARP_COMPILER_CXX_ATTRIBUTE_DEPRECATED
# define YARP_DEPRECATED_TYPEDEF YARP_DEPRECATED typedef
# define YARP_DEPRECATED_TYPEDEF_MSG(x) YARP_DEPRECATED_MSG(x) typedef
#else
# define YARP_DEPRECATED_TYPEDEF typedef YARP_DEPRECATED
# define YARP_DEPRECATED_TYPEDEF_MSG(x) typedef YARP_DEPRECATED_MSG(x)
#endif


// Due to a GCC bug, it is not a good idea to mix C++14 and compiler-specific attributes
// For this reason, only for usage with visibility macro, we define the compiler-specific attributes
// See https://github.com/robotology/yarp/issues/1531
#if defined YARP_NO_DEPRECATED_WARNINGS
#  define YARP_DEPRECATED_COMPILER_SPECIFIC
#  define YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(x)
#elif YARP_COMPILER_IS_GNU || YARP_COMPILER_IS_Clang
#  define YARP_DEPRECATED_COMPILER_SPECIFIC __attribute__((__deprecated__))
#  define YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(MSG) __attribute__((__deprecated__(MSG)))
#elif YARP_COMPILER_IS_MSVC
#  define YARP_DEPRECATED_COMPILER_SPECIFIC __declspec(deprecated)
#  define YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(MSG) __declspec(deprecated(MSG))
#else
#  define YARP_DEPRECATED_COMPILER_SPECIFIC
#  define YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(MSG)
#endif

#ifdef YARP_NO_DEPRECATED
#  define YARP_DEPRECATED_EXPORT YARP_DEPRECATED YARP_EXPORT
#  define YARP_DEPRECATED_IMPORT YARP_DEPRECATED YARP_IMPORT
#  define YARP_DEPRECATED_MSG_EXPORT(X) YARP_DEPRECATED_MSG(X) YARP_EXPORT
#  define YARP_DEPRECATED_MSG_IMPORT(X) YARP_DEPRECATED_MSG(X) YARP_IMPORT
#else
#  define YARP_DEPRECATED_API // YARP_DEPRECATED Since YARP 3.5
#  define YARP_DEPRECATED_API_MSG(X) // YARP_DEPRECATED Since YARP 3.5
#  define YARP_DEPRECATED_EXPORT YARP_DEPRECATED_COMPILER_SPECIFIC YARP_EXPORT
#  define YARP_DEPRECATED_IMPORT YARP_DEPRECATED_COMPILER_SPECIFIC YARP_IMPORT
#  define YARP_DEPRECATED_MSG_EXPORT(X) YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(X) YARP_EXPORT
#  define YARP_DEPRECATED_MSG_IMPORT(X) YARP_DEPRECATED_COMPILER_SPECIFIC_MSG(X) YARP_IMPORT
#endif

#ifdef BUILDING_YARP
#  define YARP_DEPRECATED_INTERNAL YARP_DEPRECATED
#  define YARP_DEPRECATED_INTERNAL_MSG(X) YARP_DEPRECATED_MSG(X)
#else
#  define YARP_DEPRECATED_INTERNAL
#  define YARP_DEPRECATED_INTERNAL_MSG(X)
#endif

// YARP_NODISCARD: print a warning if the result unused
#if (YARP_COMPILER_IS_GNU && (__GNUC__ >= 4)) || YARP_COMPILER_IS_Clang || YARP_COMPILER_IS_AppleClang
#  define YARP_NODISCARD __attribute__ ((warn_unused_result))
#elif YARP_COMPILER_IS_MSVC && (_MSC_VER >= 1700)
#  define YARP_NODISCARD _Check_return_
#else
#  define YARP_NODISCARD
#endif

// YARP_NORETURN
#if YARP_COMPILER_CXX_ATTRIBUTES
#  define YARP_NORETURN [[noreturn]]
#else
#  define YARP_NORETURN
#endif

// YARP_UNUSED: Suppress unused variable warnings
#define YARP_UNUSED(var) (void)var


#endif // YARP_CONF_API_H
