macros.hpp 4.05 KB
Newer Older
1
//
2
// Copyright (c) 2017-2019 CNRS INRIA
3
4
//

5
6
#ifndef __pinocchio_macros_hpp__
#define __pinocchio_macros_hpp__
7

8
9
10
11
#if __cplusplus >= 201103L
  #define PINOCCHIO_WITH_CXX11_SUPPORT
#endif

12
13
14
15
16
17
18
19
#if __cplusplus >= 201403L
  #define PINOCCHIO_WITH_CXX14_SUPPORT
#endif

#if __cplusplus >= 201703L
  #define PINOCCHIO_WITH_CXX17_SUPPORT
#endif

20
21
#define PINOCCHIO_STRING_LITERAL(string) #string

22
#include <exception>
23
#include <stdexcept>
24

25
26
27
28
29
#if defined(__GNUC__) || defined(__clang__)
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wvariadic-macros"
#endif

30
/// \brief Macro to check an assert-like condition and throw a runtime error exception (with a message) if violated.
31
#define PINOCCHIO_THROW(condition,exception_type,message) \
32
  if (!(condition)) { throw exception_type(PINOCCHIO_STRING_LITERAL(message)); }
33
34
35

#define _PINOCCHIO_GET_OVERRIDE(_1, _2, MACRO_NAME, ...) MACRO_NAME

Justin Carpentier's avatar
Justin Carpentier committed
36
#define _PINOCCHIO_CHECK_INPUT_ARGUMENT_2(condition, message) \
37
38
  PINOCCHIO_THROW(condition,std::invalid_argument,PINOCCHIO_STRING_LITERAL(message))

Justin Carpentier's avatar
Justin Carpentier committed
39
40
#define _PINOCCHIO_CHECK_INPUT_ARGUMENT_1(condition) \
  _PINOCCHIO_CHECK_INPUT_ARGUMENT_2(condition,"Please check the dimensions of all input arguments.")
41

Justin Carpentier's avatar
Justin Carpentier committed
42
#define _PINOCCHIO_CHECK_INPUT_ARGUMENT_0
43

Justin Carpentier's avatar
Justin Carpentier committed
44
45
46
#define PINOCCHIO_CHECK_INPUT_ARGUMENT(...) \
  _PINOCCHIO_GET_OVERRIDE(__VA_ARGS__,_PINOCCHIO_CHECK_INPUT_ARGUMENT_2,\
  _PINOCCHIO_CHECK_INPUT_ARGUMENT_1,_PINOCCHIO_CHECK_INPUT_ARGUMENT_0)(__VA_ARGS__)
47
48
49
50

#if defined(__GNUC__) || defined(__clang__)
  #pragma GCC diagnostic pop
#endif
51

52
53
54
55
56
57
58
59
60
// For more details, visit https://stackoverflow.com/questions/171435/portability-of-warning-preprocessor-directive
#if defined(__GNUC__) || defined(__clang__)
  #define PINOCCHIO_PRAGMA(x) _Pragma(#x)
  #define PINOCCHIO_PRAGMA_MESSAGE(the_message) PINOCCHIO_PRAGMA(GCC message #the_message)
  #define PINOCCHIO_PRAGMA_WARNING(the_message) PINOCCHIO_PRAGMA(GCC warning #the_message)
  #define PINOCCHIO_PRAGMA_DEPRECATED(the_message) PINOCCHIO_PRAGMA_WARNING(Deprecated: #the_message)
  #define PINOCCHIO_PRAGMA_DEPRECATED_HEADER(old_header,new_header) \
          PINOCCHIO_PRAGMA_WARNING(Deprecated header file: #old_header has been replaced by #new_header.\n Please use #new_header instead of #old_header.)
#endif
61

62
/// \brief Macro to check the current Pinocchio version against a version provided by x.y.z
Justin Carpentier's avatar
Justin Carpentier committed
63
64
65
66
#define PINOCCHIO_VERSION_AT_LEAST(x,y,z) \
          (PINOCCHIO_MAJOR_VERSION>x || (PINOCCHIO_MAJOR_VERSION>=x && \
          (PINOCCHIO_MINOR_VERSION>y || (PINOCCHIO_MINOR_VERSION>=y && \
          PINOCCHIO_PATCH_VERSION>=z))))
67

68
69
70
// This macro can be used to prevent from macro expansion, similarly to EIGEN_NOT_A_MACRO
#define PINOCCHIO_NOT_A_MACRO

71
namespace pinocchio
72
{
73
  namespace helper
74
75
76
77
78
79
  {
    template<typename T> struct argument_type;
    template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
  }
}

80
/// \brief Empty macro argument
jcarpent's avatar
jcarpent committed
81
82
#define PINOCCHIO_MACRO_EMPTY_ARG

83
84
85
/// \brief Helper to declare that a parameter is unused
#define PINOCCHIO_UNUSED_VARIABLE(var) (void)(var)

86
87
88
89
90
/// Ensure that a matrix (or vector) is of correct size (compile-time and run-time assertion)
#define PINOCCHIO_ASSERT_MATRIX_SPECIFIC_SIZE(type,M,nrows,ncols)              \
  EIGEN_STATIC_ASSERT(   (type::RowsAtCompileTime == Eigen::Dynamic || type::RowsAtCompileTime == nrows) \
                      && (type::ColsAtCompileTime == Eigen::Dynamic || type::ColsAtCompileTime == ncols),\
                      THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE);    \
91
  assert(M.rows()==nrows && M.cols()==ncols);
92

93
94
95
96
97
98
/// Static assertion.
/// \param condition a boolean convertible expression
/// \param msg a valid C++ variable name.
#define PINOCCHIO_STATIC_ASSERT(condition,msg)                                 \
  { int msg[(condition) ? 1 : -1]; /*avoid unused-variable warning*/ (void) msg; }

99
namespace pinocchio
100
101
102
103
104
105
106
107
108
109
110
{
  namespace helper
  {
    template<typename D, template<typename> class TypeAccess>
    struct handle_return_type_without_typename
    {
      typedef typename TypeAccess< typename argument_type<void(D)>::type >::type type;
    };
  }
}

111
#endif // ifndef __pinocchio_macros_hpp__