generic_type.cpp
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 #include "generic_type_internal.hpp"
27 #include "casadi_misc.hpp"
28 #include "exception.hpp"
29 #include "serializing_stream.hpp"
30 #include <cmath>
31 
32 #include "function.hpp"
33 
34 namespace casadi {
35 
43  std::vector< std::vector<double> > > DoubleVectorVectorType;
47  std::vector< std::vector<casadi_int> > > IntVectorVectorType;
50  std::vector<std::vector<std::string> > > StringVectorVectorType;
56  std::vector< std::vector<GenericType> > > VectorVectorType;
60 
61  bool GenericType::can_cast_to(TypeID other) const {
62  switch (other) {
63  case OT_BOOL:
64  return is_bool() || is_int() || is_double();
65  case OT_BOOLVECTOR:
67  || is_bool() || is_int() || is_double();
68  case OT_INT:
69  case OT_DOUBLE:
70  return is_bool() || is_int() || is_double();
71  case OT_INTVECTOR:
72  case OT_DOUBLEVECTOR:
74  || is_bool() || is_int() || is_double();
75  case OT_INTVECTORVECTOR:
78  case OT_STRINGVECTOR:
80  case OT_VECTOR:
81  return is_vector() || is_double_vector() || is_int_vector() || is_string_vector() ||
85  case OT_VECTORVECTOR:
86  return is_vector_vector() ||
88  case OT_VOIDPTR:
89  return is_void_pointer() || is_int();
90  default:
91  return getType() == other;
92  }
93  }
94 
96  switch (type) {
97  case OT_INTVECTOR:
98  return std::vector<casadi_int>();
99  case OT_INTVECTORVECTOR:
100  return std::vector< std::vector<casadi_int> >();
101  case OT_BOOLVECTOR:
102  return std::vector<bool>();
103  case OT_DOUBLEVECTOR:
104  return std::vector<double>();
106  return std::vector< std::vector<double> >();
107  case OT_STRINGVECTOR:
108  return std::vector<std::string>();
110  return std::vector<std::vector<std::string> >();
111  case OT_DICTVECTOR:
112  return std::vector<GenericType::Dict>();
113  case OT_VECTORVECTOR:
114  return std::vector<std::vector< GenericType> >();
115  case OT_VECTOR:
116  return std::vector<GenericType>();
117  default:
118  casadi_error("empty_from_type. Unsupported type " + str(type));
119  }
120  }
121 
123  switch (type) {
124  case OT_BOOL:
125  return "OT_BOOL";
126  case OT_INT:
127  return "OT_INT";
128  case OT_DOUBLE:
129  return "OT_DOUBLE";
130  case OT_STRING:
131  return "OT_STRING";
132  case OT_INTVECTOR:
133  return "OT_INTVECTOR";
134  case OT_INTVECTORVECTOR:
135  return "OT_INTVECTORVECTOR";
136  case OT_BOOLVECTOR:
137  return "OT_BOOLVECTOR";
138  case OT_DOUBLEVECTOR:
139  return "OT_DOUBLEVECTOR";
141  return "OT_DOUBLEVECTORVECTOR";
142  case OT_STRINGVECTOR:
143  return "OT_STRINGVECTOR";
145  return "OT_STRINGVECTORVECTOR";
146  case OT_DICT:
147  return "OT_DICT";
148  case OT_DICTVECTOR:
149  return "OT_DICTVECTOR";
150  case OT_VECTORVECTOR:
151  return "OT_VECTORVECTOR";
152  case OT_VECTOR:
153  return "OT_VECTOR";
154  case OT_FUNCTION:
155  return "OT_FUNCTION";
156  case OT_FUNCTIONVECTOR:
157  return "OT_FUNCTIONVECTOR";
158  case OT_VOIDPTR:
159  return "OT_VOIDPTR";
160  default:
161  return "OT_UNKNOWN";
162 
163  }
164  }
165 
166 
167  bool GenericType::is_bool() const {
168  return getType()==OT_BOOL;
169  }
170 
171  bool GenericType::is_int() const {
172  return getType()==OT_INT;
173  }
174 
175  bool GenericType::is_double() const {
176  return getType()==OT_DOUBLE;
177  }
178 
179  bool GenericType::is_string() const {
180  return getType()==OT_STRING;
181  }
182 
184  return (is_int_vector() && to_int_vector().empty()) ||
185  (is_int_vector_vector() && to_int_vector_vector().empty()) ||
187  (is_double_vector() && to_double_vector().empty()) ||
188  (is_string_vector() && to_string_vector().empty()) ||
190  (is_bool_vector() && to_bool_vector().empty()) ||
191  (is_dict_vector() && as_dict_vector().empty()) ||
192  (is_vector_vector() && to_vector_vector().empty()) ||
193  (is_vector() && to_vector().empty());
194  }
195 
197  return getType()==OT_INTVECTOR;
198  }
199 
201  return getType()==OT_BOOLVECTOR;
202  }
203 
205  return getType()==OT_INTVECTORVECTOR;
206  }
207 
209  return getType()==OT_DOUBLEVECTOR;
210  }
211 
213  return getType()==OT_DOUBLEVECTORVECTOR;
214  }
215 
217  return getType()==OT_STRINGVECTOR;
218  }
219 
221  return getType()==OT_STRINGVECTORVECTOR;
222  }
223 
225  return getType()==OT_FUNCTION;
226  }
227 
229  return getType()==OT_FUNCTIONVECTOR;
230  }
231 
233  return getType()==OT_VOIDPTR;
234  }
235 
236  bool GenericType::is_dict() const {
237  return getType()==OT_DICT;
238  }
239 
241  return getType()==OT_DICTVECTOR;
242  }
243 
245  return getType()==OT_VECTORVECTOR;
246  }
247 
248  bool GenericType::is_vector() const {
249  return getType()==OT_VECTOR;
250  }
251 
253  }
254 
256  own(new BoolType(b));
257  }
258 
259  GenericType::GenericType(casadi_int i) {
260  own(new IntType(i));
261  }
262 
264  own(new DoubleType(d));
265  }
266 
267  GenericType::GenericType(const std::vector<casadi_int>& iv) {
268  own(new IntVectorType(iv));
269  }
270 
271  GenericType::GenericType(const std::vector<int>& iv) {
272  std::vector<casadi_int> temp(iv.size());
273  std::copy(iv.begin(), iv.end(), temp.begin());
274  own(new IntVectorType(temp));
275  }
276 
277  GenericType::GenericType(const std::vector<std::vector<casadi_int> >& ivv) {
278  own(new IntVectorVectorType(ivv));
279  }
280 
281  GenericType::GenericType(const std::vector<bool>& b_vec) {
282  std::vector<bool> i_vec(b_vec.size());
283  std::copy(b_vec.begin(), b_vec.end(), i_vec.begin());
284  own(new BoolVectorType(i_vec));
285  }
286 
287  GenericType::GenericType(const std::vector<double>& dv) {
288  own(new DoubleVectorType(dv));
289  }
290 
291  GenericType::GenericType(const std::vector< std::vector<double> >& dv) {
292  own(new DoubleVectorVectorType(dv));
293  }
294 
295  GenericType::GenericType(const std::vector<std::string>& sv) {
296  own(new StringVectorType(sv));
297  }
298 
299  GenericType::GenericType(const std::vector<std::vector<std::string> >& sv) {
300  own(new StringVectorVectorType(sv));
301  }
302 
303  GenericType::GenericType(const std::string& s) {
304  own(new StringType(s));
305  }
306 
307  GenericType::GenericType(const char s[]) {
308  own(new StringType(s));
309  }
310 
312  own(new FunctionType(f));
313  }
314 
315  GenericType::GenericType(const std::vector<Function>& f) {
316  own(new FunctionVectorType(f));
317  }
318 
319  const bool& GenericType::as_bool() const {
320  casadi_assert_dev(is_bool());
321  return static_cast<const BoolType*>(get())->d_;
322  }
323 
324  const casadi_int& GenericType::as_int() const {
325  casadi_assert_dev(is_int());
326  return static_cast<const IntType*>(get())->d_;
327  }
328 
329  const double& GenericType::as_double() const {
330  casadi_assert_dev(is_double());
331  return static_cast<const DoubleType*>(get())->d_;
332  }
333 
334  const std::string& GenericType::as_string() const {
335  casadi_assert_dev(is_string());
336  return static_cast<const StringType*>(get())->d_;
337  }
338 
339  const std::vector<casadi_int>& GenericType::as_int_vector() const {
340  casadi_assert_dev(is_int_vector());
341  return static_cast<const IntVectorType*>(get())->d_;
342  }
343 
344  const std::vector<bool>& GenericType::as_bool_vector() const {
345  casadi_assert_dev(is_bool_vector());
346  return static_cast<const BoolVectorType*>(get())->d_;
347  }
348 
349  const std::vector<std::vector<casadi_int> >& GenericType::as_int_vector_vector() const {
350  casadi_assert_dev(is_int_vector_vector());
351  return static_cast<const IntVectorVectorType*>(get())->d_;
352  }
353 
354  const std::vector<double>& GenericType::as_double_vector() const {
355  casadi_assert_dev(is_double_vector());
356  return static_cast<const DoubleVectorType*>(get())->d_;
357  }
358 
359  const std::vector< std::vector<double> >& GenericType::as_double_vector_vector() const {
360  casadi_assert_dev(is_double_vector_vector());
361  return static_cast<const DoubleVectorVectorType*>(get())->d_;
362  }
363 
364  const std::vector<std::string>& GenericType::as_string_vector() const {
365  casadi_assert_dev(is_string_vector());
366  return static_cast<const StringVectorType*>(get())->d_;
367  }
368 
369  const std::vector<std::vector<std::string> >& GenericType::as_string_vector_vector() const {
370  casadi_assert_dev(is_string_vector_vector());
371  return static_cast<const StringVectorVectorType*>(get())->d_;
372  }
373 
375  casadi_assert_dev(is_dict());
376  return static_cast<const DictType*>(get())->d_;
377  }
378 
379  const std::vector<GenericType::Dict>& GenericType::as_dict_vector() const {
380  casadi_assert_dev(is_dict_vector());
381  return static_cast<const DictVectorType*>(get())->d_;
382  }
383 
384  const std::vector<std::vector<GenericType> >& GenericType::as_vector_vector() const {
385  casadi_assert_dev(is_vector_vector());
386  return static_cast<const VectorVectorType*>(get())->d_;
387  }
388 
389  const std::vector<GenericType>& GenericType::as_vector() const {
390  casadi_assert_dev(is_vector());
391  return static_cast<const VectorType*>(get())->d_;
392  }
393 
395  casadi_assert_dev(is_function());
396  return static_cast<const FunctionType*>(get())->d_;
397  }
398 
399  const std::vector<Function>& GenericType::as_function_vector() const {
400  casadi_assert_dev(is_function_vector());
401  return static_cast<const FunctionVectorType*>(get())->d_;
402  }
403 
404  void* const & GenericType::as_void_pointer() const {
405  casadi_assert_dev(is_void_pointer());
406  return static_cast<const VoidPointerType*>(get())->d_;
407  }
408 
409  bool GenericType::to_bool() const {
410  if (is_bool()) {
411  return as_bool();
412  } else if (is_int()) {
413  return static_cast<bool>(to_int());
414  } else {
415  casadi_assert(is_bool(), "type mismatch");
416  return false;
417  }
418  }
419 
420  casadi_int GenericType::to_int() const {
421  if (is_double()) {
422  return static_cast<casadi_int>(to_double());
423  } else if (is_bool()) {
424  return static_cast<casadi_int>(to_bool());
425  } else {
426  casadi_assert(is_int(), "type mismatch");
427  return as_int();
428  }
429  }
430 
431  double GenericType::to_double() const {
432  if (is_bool()) {
433  return static_cast<double>(to_bool());
434  } else if (is_int()) {
435  return static_cast<double>(to_int());
436  } else {
437  casadi_assert(is_double(), "type mismatch");
438  return as_double();
439  }
440  }
441 
442  std::string GenericType::to_string() const {
443  casadi_assert(is_string(), "type mismatch");
444  return as_string();
445  }
446 
447  std::vector<int> GenericType::to_int_type_vector() const {
448  casadi_assert(is_int_vector(), "type mismatch");
449  return casadi::to_int(as_int_vector());
450  }
451 
452  std::vector<casadi_int> GenericType::to_int_vector() const {
453  if (is_bool()) {
454  return std::vector<casadi_int>(1, as_bool() ? 1 : 0);
455  } else if (is_int()) {
456  return std::vector<casadi_int>(1, as_int());
457  } else if (is_double()) {
458  return std::vector<casadi_int>(1, static_cast<casadi_int>(as_double()));
459  }
460  casadi_assert(is_int_vector(), "type mismatch");
461  return as_int_vector();
462  }
463 
464  GenericType::operator std::vector<int>() const {
465  std::vector<int> ret;
466  std::vector<casadi_int> source = to_int_vector();
467  return casadi::to_int(source);
468  }
469 
470  std::vector<bool> GenericType::to_bool_vector() const {
471  if (is_bool()) {
472  return std::vector<bool>(1, as_bool());
473  } else if (is_int()) {
474  casadi_int v = as_int();
475  casadi_assert(v==0 || v==1, "Entry must be zero or one");
476  return std::vector<bool>(1, v==1);
477  } else if (is_double()) {
478  double v = as_double();
479  casadi_assert(v==0.0 || v==1.0, "Entry must be zero or one");
480  return std::vector<bool>(1, v==1.0);
481  } else if (is_bool_vector()) {
482  return as_bool_vector();
483  }
484  casadi_assert(is_int_vector(), "type mismatch");
485  std::vector<casadi_int> v = to_int_vector();
486  std::vector<bool> ret(v.size());
487  for (casadi_int i=0; i<v.size(); ++i) {
488  casadi_assert(v[i]==0 || v[i]==1, "Entries must be zero or one");
489  ret[i] = v[i]==1;
490  }
491  return ret;
492  }
493 
494  std::vector<std::vector<casadi_int> > GenericType::to_int_vector_vector() const {
495  casadi_assert(is_int_vector_vector(), "type mismatch");
496  return as_int_vector_vector();
497  }
498 
499  std::vector<double> GenericType::to_double_vector() const {
500  if (is_bool()) {
501  return std::vector<double>(1, as_bool() ? 1.0 : 0.0);
502  } else if (is_int()) {
503  return std::vector<double>(1, static_cast<double>(as_int()));
504  } else if (is_double()) {
505  return std::vector<double>(1, as_double());
506  } else if (is_int_vector()) {
507  auto v = as_int_vector();
508  return std::vector<double>(v.begin(), v.end());
509  } else {
510  casadi_assert(is_double_vector(), "type mismatch");
511  return as_double_vector();
512  }
513  }
514 
515  std::vector< std::vector<double> > GenericType::to_double_vector_vector() const {
516  if (is_int_vector_vector()) {
517  auto v = as_int_vector_vector();
518  std::vector< std::vector<double> > ret(v.size());
519  for (casadi_int i=0;i<v.size();++i)
520  ret[i].assign(v[i].begin(), v[i].end());
521  return ret;
522  } else {
523  casadi_assert(is_double_vector_vector(), "type mismatch");
524  return as_double_vector_vector();
525  }
526  }
527 
528  std::vector<std::string> GenericType::to_string_vector() const {
529  if (is_string()) {
530  std::string s = as_string();
531  return std::vector<std::string>(1, s);
532  } else if (is_double_vector()) {
533  auto v = as_double_vector();
534  casadi_assert(v.empty(), "Cast only permitted for zero-length vectors");
535  return {};
536  } else if (is_int_vector()) {
537  auto v = as_int_vector();
538  casadi_assert(v.empty(), "Cast only permitted for zero-length vectors");
539  return {};
540  } else {
541  casadi_assert(is_string_vector(), "type mismatch");
542  return as_string_vector();
543  }
544  }
545 
546  std::vector<std::vector<std::string> > GenericType::to_string_vector_vector() const {
547  casadi_assert(is_string_vector_vector(), "type mismatch");
548  return as_string_vector_vector();
549  }
550 
552  casadi_assert(is_dict(), "type mismatch");
553  return as_dict();
554  }
555 
556  std::vector<Dict> GenericType::to_dict_vector() const {
557  if (is_empty_vector()) return {};
558  if (is_dict()) {
559  Dict e = as_dict();
560  return std::vector<Dict>(1, e);
561  }
562  casadi_assert(is_dict_vector(), "type mismatch");
563  return as_dict_vector();
564  }
565 
566  std::vector<GenericType> GenericType::to_vector() const {
567  if (is_double_vector()) {
568  auto v = as_double_vector();
569  std::vector<GenericType> ret(v.size());
570  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
571  return ret;
572  } else if (is_int_vector()) {
573  auto v = as_int_vector();
574  std::vector<GenericType> ret(v.size());
575  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
576  return ret;
577  } else if (is_string_vector()) {
578  auto v = as_string_vector();
579  std::vector<GenericType> ret(v.size());
580  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
581  return ret;
582  } else if (is_function_vector()) {
583  auto v = as_function_vector();
584  std::vector<GenericType> ret(v.size());
585  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
586  return ret;
587  } else if (is_double_vector_vector()) {
588  auto v = as_double_vector_vector();
589  std::vector<GenericType> ret(v.size());
590  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
591  return ret;
592  } else if (is_int_vector_vector()) {
593  auto v = as_int_vector_vector();
594  std::vector<GenericType> ret(v.size());
595  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
596  return ret;
597  } else if (is_string_vector_vector()) {
598  auto v = as_string_vector_vector();
599  std::vector<GenericType> ret(v.size());
600  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
601  return ret;
602  } else if (is_bool_vector()) {
603  auto v = as_bool_vector();
604  std::vector<GenericType> ret(v.size());
605  for (casadi_int i=0;i<v.size();++i) ret[i] = static_cast<bool>(v[i]);
606  return ret;
607  } else if (is_dict_vector()) {
608  auto v = as_dict_vector();
609  std::vector<GenericType> ret(v.size());
610  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
611  return ret;
612  } else if (is_vector_vector()) {
613  auto v = as_vector_vector();
614  std::vector<GenericType> ret(v.size());
615  for (casadi_int i=0;i<v.size();++i) ret[i] = v[i];
616  return ret;
617  } else {
618  casadi_assert(is_vector(), "type mismatch");
619  return as_vector();
620  }
621  }
622 
623  std::vector< std::vector<GenericType> > GenericType::to_vector_vector() const {
624  if (is_double_vector_vector()) {
625  auto v = as_double_vector_vector();
626  std::vector<std::vector<GenericType> > ret(v.size());
627  for (casadi_int i=0;i<v.size();++i) {
628  ret[i].resize(v[i].size());
629  for (casadi_int j=0;j<v[i].size();++j) {
630  ret[i][j] = v[i][j];
631  }
632  }
633  return ret;
634  } else if (is_int_vector_vector()) {
635  auto v = as_int_vector_vector();
636  std::vector<std::vector<GenericType> > ret(v.size());
637  for (casadi_int i=0;i<v.size();++i) {
638  ret[i].resize(v[i].size());
639  for (casadi_int j=0;j<v[i].size();++j) {
640  ret[i][j] = v[i][j];
641  }
642  }
643  return ret;
644  } else if (is_string_vector_vector()) {
645  auto v = as_string_vector_vector();
646  std::vector<std::vector<GenericType> > ret(v.size());
647  for (casadi_int i=0;i<v.size();++i) {
648  ret[i].resize(v[i].size());
649  for (casadi_int j=0;j<v[i].size();++j) {
650  ret[i][j] = v[i][j];
651  }
652  }
653  return ret;
654  } else {
655  casadi_assert(is_vector_vector(), "type mismatch");
656  return as_vector_vector();
657  }
658  }
659 
661  casadi_assert(is_function(), "type mismatch");
662  return as_function();
663  }
664 
665  std::vector<Function> GenericType::to_function_vector() const {
666  casadi_assert(is_function_vector(), "type mismatch");
667  return as_function_vector();
668  }
669 
671  if (is_void_pointer()) {
672  return as_void_pointer();
673  } else {
674  casadi_int i = as_int();
675  casadi_assert(i==0, "Only zero pointers accepted");
676  return nullptr;
677  }
678  }
679 
680  bool GenericType::operator==(const GenericType& op2) const {
681  return !(*this != op2);
682  }
683 
684  bool GenericType::operator!=(const GenericType& op2) const {
685  if (is_string() && op2.is_string()) {
686  return to_string() != op2.to_string();
687  }
688 
689  if (is_int() && op2.is_int()) {
690  return to_int() != op2.to_int();
691  }
692 
693  if (is_double() && op2.is_double()) {
694  return to_double() != op2.to_double();
695  }
696 
697  if (is_double_vector() && op2.is_double_vector()) {
698  const std::vector<double> &v1 = to_double_vector();
699  const std::vector<double> &v2 = op2.to_double_vector();
700  if (v1.size() != v2.size()) return true;
701  for (casadi_int i=0; i<v1.size(); ++i)
702  if (v1[i] != v2[i]) return true;
703  return false;
704  }
705 
706  if (is_int_vector() && op2.is_int_vector()) {
707  const std::vector<casadi_int> &v1 = to_int_vector();
708  const std::vector<casadi_int> &v2 = op2.to_int_vector();
709  if (v1.size() != v2.size()) return true;
710  for (casadi_int i=0; i<v1.size(); ++i)
711  if (v1[i] != v2[i]) return true;
712  return false;
713  }
714 
716  const std::vector< std::vector<casadi_int> > &v1 = to_int_vector_vector();
717  const std::vector< std::vector<casadi_int> > &v2 = op2.to_int_vector_vector();
718  if (v1.size() != v2.size()) return true;
719  for (casadi_int i=0; i<v1.size(); ++i) {
720  if (v1[i].size() != v2[i].size()) return true;
721  for (casadi_int j=0; j<v1[i].size(); ++j) {
722  if (v1[i][j] != v2[i][j]) return true;
723  }
724  }
725  return false;
726  }
727 
729  const std::vector< std::vector<double> > &v1 = to_double_vector_vector();
730  const std::vector< std::vector<double> > &v2 = op2.to_double_vector_vector();
731  if (v1.size() != v2.size()) return true;
732  for (casadi_int i=0; i<v1.size(); ++i) {
733  if (v1[i].size() != v2[i].size()) return true;
734  for (casadi_int j=0; j<v1[i].size(); ++j) {
735  if (v1[i][j] != v2[i][j]) return true;
736  }
737  }
738  return false;
739  }
740 
741  // Different types
742  return true;
743  }
744 
746  own(new DictType(dict));
747  }
748 
749  GenericType::GenericType(const std::vector<Dict>& dictv) {
750  own(new DictVectorType(dictv));
751  }
752 
753  GenericType::GenericType(const std::vector<GenericType>& gv) {
754  own(new VectorType(gv));
755  }
756 
757  GenericType::GenericType(const std::vector<std::vector<GenericType> >& gvv) {
758  own(new VectorVectorType(gvv));
759  }
760 
762  own(new VoidPointerType(ptr));
763  }
764 
766  if (is_null()) {
767  return OT_NULL;
768  } else {
769  return static_cast<const GenericTypeBase*>(get())->getType();
770  }
771  }
772 
774  s.pack("GenericType::type", static_cast<int>(getType()));
775  static_cast<const GenericTypeBase*>(get())->serialize(s);
776  }
777 
779  int itype;
780  s.unpack("GenericType::type", itype);
781  TypeID type = static_cast<TypeID>(itype);
782  switch (type) {
783  case OT_STRING:
784  return StringType::deserialize(s);
785  case OT_DOUBLE:
786  return DoubleType::deserialize(s);
787  case OT_INT:
788  return IntType::deserialize(s);
789  case OT_BOOL:
790  return BoolType::deserialize(s);
791  case OT_DOUBLEVECTOR:
795  case OT_INTVECTOR:
796  return IntVectorType::deserialize(s);
797  case OT_INTVECTORVECTOR:
799  case OT_STRINGVECTOR:
803  case OT_FUNCTION:
804  return FunctionType::deserialize(s);
805  case OT_FUNCTIONVECTOR:
807  case OT_DICT:
808  return DictType::deserialize(s);
809  case OT_DICTVECTOR:
810  return DictVectorType::deserialize(s);
811  case OT_VECTOR:
812  return VectorType::deserialize(s);
813  case OT_VECTORVECTOR:
815  default:
816  casadi_error("Not implemented: " + get_type_description(type));
817  }
818  }
819 
821  GenericType ret;
822  ret.own(node);
823  return ret;
824  }
825 
826 
827  Dict combine(const Dict& first, const Dict& second, bool recurse) {
828  if (first.empty()) return second;
829  if (second.empty()) return first;
830  Dict ret = second;
831  update_dict(ret, first, recurse);
832  return ret;
833  }
834 
835  void update_dict(Dict& target, const Dict& source, bool recurse) {
836  for (auto&& e : source) {
837  if (recurse) {
838  auto it = target.find(e.first);
839  if (it!=target.end() && it->second.is_dict()) {
840  Dict local = it->second;
841  casadi_assert(e.second.is_dict(),
842  "update_dict error: Key '" + it->first + "' exists in target, "
843  "but source value is not a dict");
844  update_dict(local, e.second, recurse);
845  it->second = local;
846  continue;
847  }
848  }
849  target[e.first] = e.second;
850  }
851  }
852 
853 
854  void update_dict(Dict& target, const std::string& key,
855  const GenericType& value, bool recurse) {
856  auto it = target.find(key);
857  if (it==target.end()) {
858  target[key] = value;
859  } else {
860  // value.is_dict()
861  casadi_assert(it->second.is_dict() && value.is_dict(),
862  "update_dict error: Key '" + key + "' exists in target, but values are not dicts");
863  Dict orig = it->second;
864  update_dict(orig, value, recurse);
865  target[key] = orig;
866  }
867  }
868 
869 
870 
871  typedef GenericTypeInternal<OT_STRING, std::string> StringType;
872  typedef GenericTypeInternal<OT_DOUBLE, double> DoubleType;
873  typedef GenericTypeInternal<OT_INT, casadi_int> IntType;
874  typedef GenericTypeInternal<OT_BOOL, bool> BoolType;
875  typedef GenericTypeInternal<OT_DOUBLEVECTOR, std::vector<double> > DoubleVectorType;
876  typedef GenericTypeInternal<OT_DOUBLEVECTORVECTOR,
877  std::vector< std::vector<double> > > DoubleVectorVectorType;
878  typedef GenericTypeInternal<OT_INTVECTOR, std::vector<casadi_int> > IntVectorType;
879  typedef GenericTypeInternal<OT_INTVECTORVECTOR,
880  std::vector< std::vector<casadi_int> > > IntVectorVectorType;
881  typedef GenericTypeInternal<OT_STRINGVECTOR, std::vector<std::string> > StringVectorType;
882  typedef GenericTypeInternal<OT_FUNCTION, Function> FunctionType;
883  typedef GenericTypeInternal<OT_FUNCTIONVECTOR, std::vector<Function> > FunctionVectorType;
884  typedef GenericTypeInternal<OT_DICT, Dict> DictType;
885  typedef GenericTypeInternal<OT_DICTVECTOR, std::vector<Dict> > DictVectorType;
886  typedef GenericTypeInternal<OT_VECTOR, std::vector<GenericType> > VectorType;
887  typedef GenericTypeInternal<OT_VECTORVECTOR,
888  std::vector<std::vector< GenericType> > > VectorVectorType;
889  typedef GenericTypeInternal<OT_VOIDPTR, void*> VoidPointerType;
890 } // namespace casadi
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
Function object.
Definition: function.hpp:60
SharedObjectInternal * get() const
Get a const pointer to the node.
void assign(SharedObjectInternal *node)
Assign the node to a node class pointer without reference counting.
static GenericType deserialize(DeserializingStream &s)
Generic data type, can hold different types such as bool, casadi_int, std::string etc.
const std::vector< double > & as_double_vector() const
Cast to the internal type.
std::vector< std::vector< casadi_int > > to_int_vector_vector() const
Convert to a type.
bool is_string() const
Check if a particular type.
bool operator==(const GenericType &op2) const
Equality.
std::map< std::string, GenericType > Dict
C++ equivalent of Python's dict or MATLAB's struct.
const std::vector< Dict > & as_dict_vector() const
Cast to the internal type.
const casadi_int & as_int() const
Cast to the internal type.
static GenericType deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static std::string get_type_description(TypeID type)
Get a description of a type.
std::vector< std::vector< GenericType > > to_vector_vector() const
Convert to a type.
const double & as_double() const
Cast to the internal type.
void serialize(SerializingStream &s) const
Serialize an object.
std::string to_string() const
Convert to a type.
bool is_void_pointer() const
Check if a particular type.
std::vector< Function > to_function_vector() const
Convert to a type.
const std::vector< std::string > & as_string_vector() const
Cast to the internal type.
bool is_string_vector_vector() const
Check if a particular type.
const std::vector< std::vector< std::string > > & as_string_vector_vector() const
Cast to the internal type.
const std::vector< std::vector< casadi_int > > & as_int_vector_vector() const
Cast to the internal type.
bool is_bool() const
Check if a particular type.
std::vector< std::vector< double > > to_double_vector_vector() const
Convert to a type.
const bool & as_bool() const
Cast to the internal type.
bool is_empty_vector() const
Check if a particular type.
void * to_void_pointer() const
Convert to a type.
Dict to_dict() const
Convert to a type.
std::vector< double > to_double_vector() const
Convert to a type.
bool is_int_vector() const
Check if a particular type.
const std::vector< GenericType > & as_vector() const
Cast to the internal type.
Function to_function() const
Convert to a type.
std::vector< casadi_int > to_int_vector() const
Convert to a type.
std::vector< GenericType > to_vector() const
Convert to a type.
static GenericType create(SharedObjectInternal *node)
Create from node.
bool is_dict_vector() const
Check if a particular type.
const std::vector< std::vector< double > > & as_double_vector_vector() const
Cast to the internal type.
std::vector< int > to_int_type_vector() const
Convert to a type.
bool is_string_vector() const
Check if a particular type.
bool is_vector_vector() const
Check if a particular type.
bool is_function_vector() const
Check if a particular type.
bool operator!=(const GenericType &op2) const
double to_double() const
Convert to a type.
bool is_bool_vector() const
Check if a particular type.
bool is_double() const
Check if a particular type.
bool is_function() const
Check if a particular type.
const std::vector< std::vector< GenericType > > & as_vector_vector() const
Cast to the internal type.
bool is_int_vector_vector() const
Check if a particular type.
casadi_int to_int() const
Convert to a type.
bool is_dict() const
Check if a particular type.
const Function & as_function() const
Cast to the internal type.
std::vector< std::string > to_string_vector() const
Convert to a type.
bool is_double_vector_vector() const
Check if a particular type.
void *const & as_void_pointer() const
Cast to the internal type.
std::vector< Dict > to_dict_vector() const
Convert to a type.
GenericType()
Default constructor.
bool to_bool() const
Convert to a type.
bool is_vector() const
Check if a particular type.
bool is_double_vector() const
Check if a particular type.
bool can_cast_to(TypeID other) const
TypeID getType() const
std::vector< std::vector< std::string > > to_string_vector_vector() const
Convert to a type.
std::vector< bool > to_bool_vector() const
Convert to a type.
const std::string & as_string() const
Cast to the internal type.
bool is_int() const
Check if a particular type.
static GenericType from_type(TypeID type)
Construct a GenericType given an TypeID.
const std::vector< Function > & as_function_vector() const
Cast to the internal type.
const Dict & as_dict() const
Cast to the internal type.
const std::vector< casadi_int > & as_int_vector() const
Cast to the internal type.
const std::vector< bool > & as_bool_vector() const
Cast to the internal type.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
The casadi namespace.
Definition: archiver.cpp:28
GenericTypeInternal< OT_VOIDPTR, void * > VoidPointerType
GenericTypeInternal< OT_INT, casadi_int > IntType
GenericTypeInternal< OT_FUNCTION, Function > FunctionType
Dict combine(const Dict &first, const Dict &second, bool recurse)
Combine two dicts. First has priority.
int to_int(casadi_int rhs)
Definition: casadi_misc.cpp:60
GenericTypeInternal< OT_INTVECTOR, std::vector< casadi_int > > IntVectorType
GenericTypeInternal< OT_DOUBLE, double > DoubleType
GenericTypeInternal< OT_STRING, std::string > StringType
GenericTypeInternal< OT_DICTVECTOR, std::vector< Dict > > DictVectorType
TypeID
Types of options.
@ OT_STRINGVECTOR
@ OT_STRINGVECTORVECTOR
@ OT_BOOLVECTOR
@ OT_INTVECTOR
@ OT_FUNCTIONVECTOR
@ OT_DOUBLEVECTORVECTOR
@ OT_DICTVECTOR
@ OT_VECTORVECTOR
@ OT_INTVECTORVECTOR
@ OT_DOUBLEVECTOR
GenericTypeInternal< OT_DOUBLEVECTORVECTOR, std::vector< std::vector< double > > > DoubleVectorVectorType
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
GenericTypeInternal< OT_INTVECTORVECTOR, std::vector< std::vector< casadi_int > > > IntVectorVectorType
void update_dict(Dict &target, const Dict &source, bool recurse)
Update the target dictionary in place with source elements.
GenericTypeInternal< OT_DOUBLEVECTOR, std::vector< double > > DoubleVectorType
GenericTypeInternal< OT_STRINGVECTOR, std::vector< std::string > > StringVectorType
GenericTypeInternal< OT_BOOL, bool > BoolType
GenericTypeInternal< OT_VECTOR, std::vector< GenericType > > VectorType
GenericTypeInternal< OT_BOOLVECTOR, std::vector< bool > > BoolVectorType
GenericTypeInternal< OT_FUNCTIONVECTOR, std::vector< Function > > FunctionVectorType
GenericTypeInternal< OT_VECTORVECTOR, std::vector< std::vector< GenericType > > > VectorVectorType
GenericTypeInternal< OT_STRINGVECTORVECTOR, std::vector< std::vector< std::string > > > StringVectorVectorType
GenericTypeInternal< OT_DICT, Dict > DictType