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 
187  template<typename T, size_t N>
188  std::string str(const std::array<T, N> &p, bool more=false);
189 
191  inline std::vector<std::string> strvec() {
192  return {};
193  }
194 
196  template<typename T1>
197  inline std::vector<std::string> strvec(const T1& t1) {
198  return {str(t1)};
199  }
200 
202  template<typename T1, typename T2>
203  inline std::vector<std::string> strvec(const T1& t1, const T2& t2) {
204  return {str(t1), str(t2)};
205  }
206 
208  template<typename T1, typename T2, typename T3>
209  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3) {
210  return {str(t1), str(t2), str(t3)};
211  }
212 
214  template<typename T1, typename T2, typename T3, typename T4>
215  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
216  const T4& t4) {
217  return {str(t1), str(t2), str(t3), str(t4)};
218  }
219 
221  template<typename T1, typename T2, typename T3, typename T4, typename T5>
222  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
223  const T4& t4, const T5& t5) {
224  return {str(t1), str(t2), str(t3), str(t4), str(t5)};
225  }
226 
228  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
229  inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
230  const T4& t4, const T5& t5, const T6& t6) {
231  return {str(t1), str(t2), str(t3), str(t4), str(t5), str(t6)};
232  }
233 
235  inline std::string fmtstr(const std::string& fmt, const std::vector<std::string>& args) {
236  std::string s = fmt;
237  for (auto&& e : args) {
238  std::string::size_type n = s.find("%s");
239  if (n==std::string::npos) return "** Ill-formatted string ** " + fmt;
240  s.replace(n, 2, e);
241  }
242  return s;
243  }
244 
245  // Implementations
246  template<typename T>
247  std::string str(const T& v) {
248  std::stringstream ss;
249  ss << v;
250  return ss.str();
251  }
252 
253  template<typename T>
254  std::string str(const T& v, bool more) {
255  return v.get_str(more);
256  }
257 
258  template<typename T>
259  std::string str(const std::vector<T>& v, bool more) {
260  std::stringstream ss;
261  ss << "[";
262  for (casadi_int i=0; i<v.size(); ++i) {
263  if (i!=0) ss << ", ";
264  ss << v[i];
265  }
266  ss << "]";
267  return ss.str();
268  }
269 
270  template<typename T>
271  std::string str(const std::set<T>& v, bool more) {
272  std::stringstream ss;
273  ss << "{";
274  casadi_int cnt = 0;
275  for (const auto& e : v) {
276  if (cnt++!=0) ss << ", ";
277  ss << e;
278  }
279  ss << "}";
280  return ss.str();
281  }
282 
283  template<typename T1, typename T2>
284  std::string str(const std::pair<T1, T2>& p, bool more) {
285  std::stringstream ss;
286  ss << "[" << p.first << "," << p.second << "]";
287  return ss.str();
288  }
289 
290  template<typename T1, typename T2>
291  std::string str(const std::map<T1, T2>& p, bool more) {
292  std::stringstream ss;
293  ss << "{";
294  casadi_int count = 0;
295  for (auto& e : p) {
296  ss << e.first << ": " << e.second;
297  if (++count < p.size()) ss << ", ";
298  }
299  ss << "}";
300  return ss.str();
301  }
302 
303  template<typename T2>
304  std::string str(const std::map<std::string, T2>& p, bool more) {
305  std::stringstream ss;
306  ss << "{";
307  casadi_int count = 0;
308  for (auto& e : p) {
309  ss << "\"" << e.first << "\": " << e.second;
310  if (++count < p.size()) ss << ", ";
311  }
312  ss << "}";
313  return ss.str();
314  }
315 
316  template<typename T, size_t N>
317  std::string str(const std::array<T, N> &v, bool more) {
318  std::stringstream ss;
319  ss << "[";
320  for (casadi_int i=0; i<N; ++i) {
321  if (i!=0) ss << ", ";
322  ss << v[i];
323  }
324  ss << "]";
325  return ss.str();
326  }
327 
328 #endif // SWIG
329 
330  template<typename _Mutex>
332  public:
333  typedef _Mutex mutex_type;
334 
335  conditional_lock_guard(mutex_type& m, bool condition) : mtx_(m), condition_(condition) {
336  if (condition_) mtx_.lock();
337  }
338 
340  if (condition_) mtx_.unlock();
341  }
342 
345 
346  private:
347  mutex_type& mtx_;
348  bool condition_;
349  };
350 
351 } // namespace casadi
352 
353 #include "casadi_logger.hpp"
354 
355 #endif // CASADI_COMMON_HPP
conditional_lock_guard & operator=(const conditional_lock_guard &)=delete
conditional_lock_guard(mutex_type &m, bool condition)
conditional_lock_guard(const conditional_lock_guard &)=delete
struct VariableStruct Variable
The casadi namespace.
Definition: archiver.cpp:28
unsigned long long bvec_t
int(* casadi_checkout_t)(void)
Function pointer types for the C API.
int(* diff_t)(casadi_int i)
Function pointer types for the C API.
std::string fmtstr(const std::string &fmt, const std::vector< std::string > &args)
Create a string from a formatted string.
int(* eval_t)(const double **arg, double **res, casadi_int *iw, double *w, int)
Function pointer types for the C API.
casadi_int(* getint_t)(void)
Function pointer types for the C API.
int(* config_t)(int, const char **)
Function pointer types for the C API.
constexpr casadi_int LOOKUP_BINARY
std::string str(const T &v)
String representation, any type.
void(* casadi_release_t)(int)
Function pointer types for the C API.
void(* signal_t)(void)
Function pointer types for the C API.
const int bvec_size
constexpr casadi_int LOOKUP_EXACT
constexpr casadi_int LOOKUP_LINEAR
double(* default_t)(casadi_int i)
Function pointer types for the C API.
int(* work_t)(casadi_int *sz_arg, casadi_int *sz_res, casadi_int *sz_iw, casadi_int *sz_w)
Function pointer types for the C API.
std::vector< std::string > strvec()
Create a list of strings from VA_ARGS, no argument.