1 /*
2  *    This file is part of CasADi.
3  *
4  *    CasADi -- A symbolic framework for dynamic optimization.
5  *    Copyright (C) 2010-2014 Joel Andersson, Joris Gillis, Moritz Diehl,
6  *                            K.U. 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 
65   /// Forward declarations
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 // warinng C4251: Need a dll interface?
98 #pragma warning(disable:4251)
99 
100 // warning C4715: Not all control paths return a value
101 #pragma warning(disable:4715)
102 
103 // warning C4800: 'int' : forcing value to bool 'true'or 'false'(performance warning)
104 #pragma warning(disable:4800)
105 
106 // warning C4910: __declspec(dllexport) and extern incompatible on an explicit instantiation
107 #pragma warning(disable:4910)
108 
109 // ?
110 #pragma warning(disable:4996)
111 
112 #endif // _MSC_VER
113 
114   // Macro "minor" is sometimes defined, cf.
115   // https://stackoverflow.com/questions/22240973/major-and-minor-macros-defined-in-sys-sysmacros-h-pulled-in-by-iterator
116 #undef minor
117 
118   // Type with a size corresponding to that of double (or smaller) that can be used to hold a set
119   // of booleans. If the compiler supports C99 or has defined __SIZEOF_LONG_LONG__,
120   // we shall use the long long datatype, which is 64 bits, otherwise long
121   #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L || defined(__SIZEOF_LONG_LONG__))
122   typedef unsigned long long bvec_t;
123   #else
124   typedef unsigned long bvec_t;
125   #endif
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 
134   ///@{
135   /** \brief  Function pointer types for the C API */
136   typedef void (*signal_t)(void);
137   typedef casadi_int (*getint_t)(void);
138   typedef double (*default_t)(casadi_int i);
139   typedef const char* (*name_t)(casadi_int i);
140   typedef const casadi_int* (*sparsity_t)(casadi_int i);
141   typedef int (*casadi_checkout_t)(void);
142   typedef void (*casadi_release_t)(int);
143   typedef int (*work_t)(casadi_int* sz_arg, casadi_int* sz_res,
144     casadi_int* sz_iw, casadi_int* sz_w);
145   typedef int (*eval_t)(const double** arg, double** res,
146                         casadi_int* iw, double* w, int);
147   ///@}
148 
149   // Easier to maintain than an enum (serialization/codegen)
150   constexpr casadi_int LOOKUP_LINEAR = 0;
151   constexpr casadi_int LOOKUP_EXACT = 1;
152   constexpr casadi_int LOOKUP_BINARY = 2;
153 
154   /// String representation, any type
155   template<typename T>
156   std::string str(const T& v);
157 
158   /// String representation, CasADi type
159   template<typename T>
160   std::string str(const T& v, bool more);
161 
162   /// String representation of vector
163   template<typename T>
164   std::string str(const std::vector<T>& v, bool more=false);
165 
166   /// String representation of set
167   template<typename T>
168   std::string str(const std::set<T>& v, bool more=false);
169 
170   /// String representation of pair
171   template<typename T1, typename T2>
172   std::string str(const std::pair<T1, T2>& p, bool more=false);
173 
174   /// String representation of a map
175   template<typename T1, typename T2>
176   std::string str(const std::map<T1, T2> &p, bool more=false);
177 
178   /// String representation of a dictionary
179   template<typename T2>
180   std::string str(const std::map<std::string, T2> &p, bool more=false);
181 
182 
183   //! \brief Create a list of strings from __VA_ARGS__, no argument
strvec()184   inline std::vector<std::string> strvec() {
185     return {};
186   }
187 
188   //! \brief Create a list of strings from __VA_ARGS__, one argument
189   template<typename T1>
strvec(const T1 & t1)190   inline std::vector<std::string> strvec(const T1& t1) {
191     return {str(t1)};
192   }
193 
194   //! \brief Create a list of strings from __VA_ARGS__, two arguments
195   template<typename T1, typename T2>
strvec(const T1 & t1,const T2 & t2)196   inline std::vector<std::string> strvec(const T1& t1, const T2& t2) {
197     return {str(t1), str(t2)};
198   }
199 
200   //! \brief Create a list of strings from __VA_ARGS__, three arguments
201   template<typename T1, typename T2, typename T3>
strvec(const T1 & t1,const T2 & t2,const T3 & t3)202   inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3) {
203     return {str(t1), str(t2), str(t3)};
204   }
205 
206   //! \brief Create a list of strings from __VA_ARGS__, four arguments
207   template<typename T1, typename T2, typename T3, typename T4>
strvec(const T1 & t1,const T2 & t2,const T3 & t3,const T4 & t4)208   inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
209                                          const T4& t4) {
210     return {str(t1), str(t2), str(t3), str(t4)};
211   }
212 
213   //! \brief Create a list of strings from __VA_ARGS__, five arguments
214   template<typename T1, typename T2, typename T3, typename T4, typename T5>
strvec(const T1 & t1,const T2 & t2,const T3 & t3,const T4 & t4,const T5 & t5)215   inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
216                                          const T4& t4, const T5& t5) {
217     return {str(t1), str(t2), str(t3), str(t4), str(t5)};
218   }
219 
220   //! \brief Create a list of strings from __VA_ARGS__, six arguments
221   template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
strvec(const T1 & t1,const T2 & t2,const T3 & t3,const T4 & t4,const T5 & t5,const T6 & t6)222   inline std::vector<std::string> strvec(const T1& t1, const T2& t2, const T3& t3,
223                                          const T4& t4, const T5& t5, const T6& t6) {
224     return {str(t1), str(t2), str(t3), str(t4), str(t5), str(t6)};
225   }
226 
227   //! \brief Create a string from a formated string
fmtstr(const std::string & fmt,const std::vector<std::string> & args)228   inline std::string fmtstr(const std::string& fmt, const std::vector<std::string>& args) {
229     std::string s = fmt;
230     for (auto&& e : args) {
231       std::string::size_type n = s.find("%s");
232       if (n==std::string::npos) return "** Ill-formated string ** " + fmt;
233       s.replace(n, 2, e);
234     }
235     return s;
236   }
237 
238   // Implementations
239   template<typename T>
str(const T & v)240   std::string str(const T& v) {
241     std::stringstream ss;
242     ss << v;
243     return ss.str();
244   }
245 
246   template<typename T>
str(const T & v,bool more)247   std::string str(const T& v, bool more) {
248     return v.get_str(more);
249   }
250 
251   template<typename T>
str(const std::vector<T> & v,bool more)252   std::string str(const std::vector<T>& v, bool more) {
253     std::stringstream ss;
254     ss << "[";
255     for (casadi_int i=0; i<v.size(); ++i) {
256       if (i!=0) ss << ", ";
257       ss << v[i];
258     }
259     ss << "]";
260     return ss.str();
261   }
262 
263   template<typename T>
str(const std::set<T> & v,bool more)264   std::string str(const std::set<T>& v, bool more) {
265     std::stringstream ss;
266     ss << "{";
267     casadi_int cnt = 0;
268     for (const auto& e : v) {
269       if (cnt++!=0) ss << ", ";
270       ss << e;
271     }
272     ss << "}";
273     return ss.str();
274   }
275 
276   template<typename T1, typename T2>
str(const std::pair<T1,T2> & p,bool more)277   std::string str(const std::pair<T1, T2>& p, bool more) {
278     std::stringstream ss;
279     ss << "[" << p.first << "," << p.second << "]";
280     return ss.str();
281   }
282 
283   template<typename T1, typename T2>
str(const std::map<T1,T2> & p,bool more)284   std::string str(const std::map<T1, T2>& p, bool more) {
285     std::stringstream ss;
286     ss << "{";
287     casadi_int count = 0;
288     for (auto& e : p) {
289       ss << e.first << ": " << e.second;
290       if (++count < p.size()) ss << ", ";
291     }
292     ss << "}";
293     return ss.str();
294   }
295 
296   template<typename T2>
str(const std::map<std::string,T2> & p,bool more)297   std::string str(const std::map<std::string, T2>& p, bool more) {
298     std::stringstream ss;
299     ss << "{";
300     casadi_int count = 0;
301     for (auto& e : p) {
302       ss << "\"" << e.first << "\": " << e.second;
303       if (++count < p.size()) ss << ", ";
304     }
305     ss << "}";
306     return ss.str();
307   }
308 #endif // SWIG
309 
310 } // namespace casadi
311 
312 #include "casadi_logger.hpp"
313 
314 #endif // CASADI_COMMON_HPP
315