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