dynamic_object.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // This file is distributed under the BSD License.
  2. // See "license.txt" for details.
  3. // Copyright 2009-2012, Jonathan Turner ([email protected])
  4. // Copyright 2009-2017, Jason Turner ([email protected])
  5. // http://www.chaiscript.com
  6. // This is an open source non-commercial project. Dear PVS-Studio, please check it.
  7. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  8. #ifndef CHAISCRIPT_DYNAMIC_OBJECT_HPP_
  9. #define CHAISCRIPT_DYNAMIC_OBJECT_HPP_
  10. #include <map>
  11. #include <string>
  12. #include <utility>
  13. #include "boxed_value.hpp"
  14. namespace chaiscript {
  15. class Type_Conversions;
  16. namespace dispatch {
  17. class Proxy_Function_Base;
  18. } // namespace dispatch
  19. } // namespace chaiscript
  20. namespace chaiscript
  21. {
  22. namespace dispatch
  23. {
  24. struct option_explicit_set : std::runtime_error {
  25. explicit option_explicit_set(const std::string &t_param_name)
  26. : std::runtime_error("option explicit set and parameter '" + t_param_name + "' does not exist")
  27. {
  28. }
  29. option_explicit_set(const option_explicit_set &) = default;
  30. ~option_explicit_set() noexcept override = default;
  31. };
  32. class Dynamic_Object
  33. {
  34. public:
  35. explicit Dynamic_Object(std::string t_type_name)
  36. : m_type_name(std::move(t_type_name)), m_option_explicit(false)
  37. {
  38. }
  39. Dynamic_Object() = default;
  40. bool is_explicit() const
  41. {
  42. return m_option_explicit;
  43. }
  44. void set_explicit(const bool t_explicit)
  45. {
  46. m_option_explicit = t_explicit;
  47. }
  48. std::string get_type_name() const
  49. {
  50. return m_type_name;
  51. }
  52. const Boxed_Value &operator[](const std::string &t_attr_name) const
  53. {
  54. return get_attr(t_attr_name);
  55. }
  56. Boxed_Value &operator[](const std::string &t_attr_name)
  57. {
  58. return get_attr(t_attr_name);
  59. }
  60. const Boxed_Value &get_attr(const std::string &t_attr_name) const
  61. {
  62. auto a = m_attrs.find(t_attr_name);
  63. if (a != m_attrs.end()) {
  64. return a->second;
  65. } else {
  66. throw std::range_error("Attr not found '" + t_attr_name + "' and cannot be added to const obj");
  67. }
  68. }
  69. bool has_attr(const std::string &t_attr_name) const {
  70. return m_attrs.find(t_attr_name) != m_attrs.end();
  71. }
  72. Boxed_Value &get_attr(const std::string &t_attr_name)
  73. {
  74. return m_attrs[t_attr_name];
  75. }
  76. Boxed_Value &method_missing(const std::string &t_method_name)
  77. {
  78. if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
  79. throw option_explicit_set(t_method_name);
  80. }
  81. return get_attr(t_method_name);
  82. }
  83. const Boxed_Value &method_missing(const std::string &t_method_name) const
  84. {
  85. if (m_option_explicit && m_attrs.find(t_method_name) == m_attrs.end()) {
  86. throw option_explicit_set(t_method_name);
  87. }
  88. return get_attr(t_method_name);
  89. }
  90. std::map<std::string, Boxed_Value> get_attrs() const
  91. {
  92. return m_attrs;
  93. }
  94. private:
  95. const std::string m_type_name = "";
  96. bool m_option_explicit = false;
  97. std::map<std::string, Boxed_Value> m_attrs;
  98. };
  99. }
  100. }
  101. #endif