casadi_common.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_COMMON_HPP
27 #define CASADI_COMMON_HPP
28 
29 #include <algorithm>
30 #include <climits>
31 #include <cmath>
32 #include <fstream>
33 #include <iostream>
34 #include <iterator>
35 #include <limits>
36 #include <map>
37 #include <set>
38 #include <sstream>
39 #include <string>
40 #include <utility>
41 #include <vector>
42 
43 #ifdef SWIG
44 #define SWIG_IF_ELSE(is_swig, not_swig) is_swig
45 #define SWIG_OUTPUT(arg) OUTPUT
46 #define SWIG_INOUT(arg) INOUT
47 #define SWIG_CONSTREF(arg) const arg
48 #ifdef SWIGMATLAB
49 #define SWIG_IND1 true
50 #else // SWIGMATLAB
51 #define SWIG_IND1 false
52 #endif // SWIGMATLAB
53 #else // SWIG
54 #define SWIG_IF_ELSE(is_swig, not_swig) not_swig
55 #define SWIG_OUTPUT(arg) arg
56 #define SWIG_INOUT(arg) arg
57 #define SWIG_CONSTREF(arg) const arg &
58 #define SWIG_IND1 false
59 #endif // SWIG
60 
61 #include "casadi_types.hpp"
62 
63 namespace casadi {
64 
66  class SXElem;
67  class MX;
68  template<class T> class Matrix;
69  class Function;
70  class Sparsity;
71  class CodeGenerator;
72  class NlpBuilder;
73  struct Variable;
74  class DaeBuilder;
75  class XmlFile;
76  class Importer;
77 
78 #ifndef SWIG
79 // Get GCC version if GCC is used
80 #ifdef __GNUC__
81 #ifdef __GNUC_MINOR__
82 #ifdef __GNUC_PATCHLEVEL__
83 #define GCC_VERSION (__GNUC__ * 10000 +__GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
84 #endif // __GNUC_PATCHLEVEL__
85 #endif // __GNUC_MINOR__
86 #endif // __GNUC__
87 
88 // Disable some Visual studio warnings
89 #ifdef _MSC_VER
90 
91 // warning C4018: '<' : signed/unsigned mismatch
92 #pragma warning(disable:4018)
93 
94 // warning C4244: Potential loss of data converting double to int
95 #pragma warning(disable:4244)
96 
97 // warning C4251: Need a dll interface?
98 #pragma warning(disable:4251)
99 
100 // warning C4275: non dll-interface class 'std::exception' used as base for dll-interface
101 // class 'casadi::CasadiException'
102 #pragma warning(disable:4275)
103 
104 // warning C4715: Not all control paths return a value
105 #pragma warning(disable:4715)
106 
107 // warning C4800: 'int' : forcing value to bool 'true'or 'false'(performance warning)
108 #pragma warning(disable:4800)
109 
110 // warning C4910: __declspec(dllexport) and extern incompatible on an explicit instantiation
111 #pragma warning(disable:4910)
112 
113 // warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s
114 // instead
115 #pragma warning(disable:4996)
116 
117 #endif // _MSC_VER
118 
119  // Macro "minor" is sometimes defined, cf.
120  // https://stackoverflow.com/questions/22240973/major-and-minor-macros-defined-in-sys-sysmacros-h-pulled-in-by-iterator
121 #undef minor
122 
123  // Type with a size corresponding to that of double (or smaller) that can be used to hold a set
124  // of booleans
125  typedef unsigned long long bvec_t;
126 
127  // Number of directions we can deal with at a time
128  // the size of bvec_t in bits (CHAR_BIT is the number of bits per byte, usually 8)
129  const int bvec_size = CHAR_BIT*sizeof(bvec_t);
130 
131  // Make sure that the integer datatype is indeed smaller or equal to the double
132  //assert(sizeof(bvec_t) <= sizeof(double)); // doesn't work - very strange
133 
135 
138  typedef int (*config_t)(int, const char**);
139  typedef void (*signal_t)(void);
140  typedef casadi_int (*getint_t)(void);
141  typedef double (*default_t)(casadi_int i);
142  typedef const char* (*name_t)(casadi_int i);
143  typedef const casadi_int* (*sparsity_t)(casadi_int i);
144  typedef int (*diff_t)(casadi_int i);
145  typedef int (*casadi_checkout_t)(void);
146  typedef void (*casadi_release_t)(int);
147  typedef int (*work_t)(casadi_int* sz_arg, casadi_int* sz_res,
148  casadi_int* sz_iw, casadi_int* sz_w);
149  typedef int (*eval_t)(const double** arg, double** res,
150  casadi_int* iw, double* w, int);
152 
153  // Easier to maintain than an enum (serialization/codegen)
154  constexpr casadi_int LOOKUP_LINEAR = 0;
155  constexpr casadi_int LOOKUP_EXACT = 1;
156  constexpr casadi_int LOOKUP_BINARY = 2;
157 
159  template<typename T>
160  std::string str(const T& v);
161 
163  template<typename T>
164  std::string str(const T& v, bool more);
165 
167  template<typename T>
168  std::string str(const std::vector<T>& v, bool more=false);
169 
171  template<typename T>
172  std::string str(const std::set<T>& v, bool more=false);
173 
175  template<typename T1, typename T2>
176  std::string str(const std::pair<T1, T2>& p, bool more=false);
177 
179  template<typename T1, typename T2>
180  std::string str(const std::map<T1, T2> &p, bool more=false);
181 
183  template<typename T2>
184  std::string str(const std::map<std::string, T2> &p, bool more=false);
185 
186 
188  inline std::vector<std::string> strvec() {
189  return {};
190  }
191 
193  template<typename T1>
194  inline std::vector<std::string> strvec(const T1& t1) {
195  return {str(t1)};
196  }
197 
199  template<typename T1, typename T2>
200  inline std::vector<std::string> strvec(const T1& t1, const T2& t2) {
201  return {str(t1), str(t2)};
202  }
203 
205  template<typename T1, typename T2, typename T3>
206  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3) {
207  return {str(t1), str(t2), str(t3)};
208  }
209 
211  template<typename T1, typename T2, typename T3, typename T4>
212  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
213  const T4& t4) {
214  return {str(t1), str(t2), str(t3), str(t4)};
215  }
216 
218  template<typename T1, typename T2, typename T3, typename T4, typename T5>
219  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
220  const T4& t4, const T5& t5) {
221  return {str(t1), str(t2), str(t3), str(t4), str(t5)};
222  }
223 
225  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
226  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
227  const T4& t4, const T5& t5, const T6& t6) {
228  return {str(t1), str(t2), str(t3), str(t4), str(t5), str(t6)};
229  }
230 
232  inline std::string fmtstr(const std::string& fmt, const std::vector<std::string>& args) {
233  std::string s = fmt;
234  for (auto&& e : args) {
235  std::string::size_type n = s.find("%s");
236  if (n==std::string::npos) return "** Ill-formatted string ** " + fmt;
237  s.replace(n, 2, e);
238  }
239  return s;
240  }
241 
242  // Implementations
243  template<typename T>
244  std::string str(const T& v) {
245  std::stringstream ss;
246  ss << v;
247  return ss.str();
248  }
249 
250  template<typename T>
251  std::string str(const T& v, bool more) {
252  return v.get_str(more);
253  }
254 
255  template<typename T>
256  std::string str(const std::vector<T>& v, bool more) {
257  std::stringstream ss;
258  ss << "[";
259  for (casadi_int i=0; i<v.size(); ++i) {
260  if (i!=0) ss << ", ";
261  ss << v[i];
262  }
263  ss << "]";
264  return ss.str();
265  }
266 
267  template<typename T>
268  std::string str(const std::set<T>& v, bool more) {
269  std::stringstream ss;
270  ss << "{";
271  casadi_int cnt = 0;
272  for (const auto& e : v) {
273  if (cnt++!=0) ss << ", ";
274  ss << e;
275  }
276  ss << "}";
277  return ss.str();
278  }
279 
280  template<typename T1, typename T2>
281  std::string str(const std::pair<T1, T2>& p, bool more) {
282  std::stringstream ss;
283  ss << "[" << p.first << "," << p.second << "]";
284  return ss.str();
285  }
286 
287  template<typename T1, typename T2>
288  std::string str(const std::map<T1, T2>& p, bool more) {
289  std::stringstream ss;
290  ss << "{";
291  casadi_int count = 0;
292  for (auto& e : p) {
293  ss << e.first << ": " << e.second;
294  if (++count < p.size()) ss << ", ";
295  }
296  ss << "}";
297  return ss.str();
298  }
299 
300  template<typename T2>
301  std::string str(const std::map<std::string, T2>& p, bool more) {
302  std::stringstream ss;
303  ss << "{";
304  casadi_int count = 0;
305  for (auto& e : p) {
306  ss << "\"" << e.first << "\": " << e.second;
307  if (++count < p.size()) ss << ", ";
308  }
309  ss << "}";
310  return ss.str();
311  }
312 #endif // SWIG
313 
314 } // namespace casadi
315 
316 #include "casadi_logger.hpp"
317 
318 #endif // CASADI_COMMON_HPP
The casadi namespace.