api_utils.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020 by
  4. * The Salk Institute for Biological Studies
  5. *
  6. * Use of this source code is governed by an MIT-style
  7. * license that can be found in the LICENSE file or at
  8. * https://opensource.org/licenses/MIT.
  9. *
  10. ******************************************************************************/
  11. #ifndef LIBMCELL_API_API_UTILS_H_
  12. #define LIBMCELL_API_API_UTILS_H_
  13. #include <memory>
  14. #include <vector>
  15. #include "api/api_common.h"
  16. // functions defined here are not used in generated files
  17. namespace MCell {
  18. namespace API {
  19. bool is_simple_species(const std::string& name);
  20. Orientation convert_mcell_orientation(const orientation_t o);
  21. orientation_t convert_api_orientation(const Orientation o, const bool allow_default = false, const bool is_vol = true);
  22. static inline std::vector<double> mult_vec(const std::vector<double>& in, const double mult) {
  23. std::vector<double> res(in.size());
  24. for (size_t i = 0; i < in.size(); i++) {
  25. res[i] = in[i] * mult;
  26. }
  27. return res;
  28. }
  29. template<class T>
  30. void append_to_vec(
  31. std::vector<std::shared_ptr<T>>& dst,
  32. const std::shared_ptr<T>& item,
  33. const bool allow_same_name_different_contents = false) {
  34. if (!allow_same_name_different_contents) {
  35. // check if item with this name already exists
  36. for (std::shared_ptr<T>& existing: dst) {
  37. if (item->name == existing->name) {
  38. // must be identical
  39. if (!item->__eq__(*existing)) {
  40. throw ValueError(
  41. "Adding object of " + item->class_name + " with name '" + item->name +
  42. "' caused an error, object with the same name is already present but it is different, " +
  43. "\nexisting:\n" + existing->to_str() + "\nvs. new\n:" + item->to_str() + ".\n"
  44. "-- end of error message reporting existence of two objects with identical names --"
  45. );
  46. }
  47. else {
  48. std::cerr << "Warning: adding of " + item->class_name + " with name '" + item->name +
  49. "' is ignored, identical object is already present.\n";
  50. return;
  51. }
  52. }
  53. }
  54. }
  55. dst.push_back(item);
  56. }
  57. template<class T>
  58. void append_to_vec_canonical_name(
  59. std::vector<std::shared_ptr<T>>& dst,
  60. const std::shared_ptr<T>& item) {
  61. // check if item with this name already exists
  62. for (std::shared_ptr<T>& existing: dst) {
  63. bool are_equal = item->__eq__(*existing);
  64. std::string name_in_msg = "object of " + item->class_name + " with" +
  65. (is_set(item->name) ? " name '" + item->name + "' and" : S("")) +
  66. " canonical name '" + item->get_canonical_name() + "'";
  67. if (item->get_canonical_name() == existing->get_canonical_name()) {
  68. // must be identical
  69. if (!are_equal) {
  70. throw ValueError(
  71. "Adding " + name_in_msg + " caused an error, object with the same canonical name is already present but it is different, "
  72. "\nexisting:\n" + existing->to_str() + "\nvs. new:\n " + item->to_str() + ".\n"
  73. "-- end of error message reporting existence of two objects with identical names --"
  74. );
  75. }
  76. else {
  77. if (item->warn_if_adding_identical_object()) {
  78. std::cerr << "Warning: adding of " + name_in_msg + " is ignored, object with the same canonical name is already present.\n";
  79. }
  80. return;
  81. }
  82. }
  83. // also check, if name is set, that I cannot have different objects with the same name
  84. if (is_set(item->name) && item->name == existing->name && !are_equal) {
  85. throw ValueError(
  86. "Adding object of " + name_in_msg + " caused an error, object with the same name is already present but it is different."
  87. );
  88. }
  89. }
  90. dst.push_back(item);
  91. }
  92. template<class T>
  93. void append_vec_to_vec(
  94. std::vector<std::shared_ptr<T>>& dst,
  95. const std::vector<std::shared_ptr<T>>& src,
  96. const bool allow_same_name_different_contents = false
  97. ) {
  98. for (const std::shared_ptr<T>& item: src) {
  99. append_to_vec(
  100. dst, item, allow_same_name_different_contents);
  101. }
  102. }
  103. template<class T>
  104. void append_vec_to_vec_canonical_name(
  105. std::vector<std::shared_ptr<T>>& dst,
  106. const std::vector<std::shared_ptr<T>>& src
  107. ) {
  108. for (const std::shared_ptr<T>& item: src) {
  109. append_to_vec_canonical_name(dst, item);
  110. }
  111. }
  112. } // namespace API
  113. } // namespace MCell
  114. #endif // LIBMCELL_API_API_UTILS_H_