You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

any.h 5.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /**
  2. * Copyright 2019-2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef MINDSPORE_CORE_UTILS_ANY_H_
  17. #define MINDSPORE_CORE_UTILS_ANY_H_
  18. #include <iostream>
  19. #include <string>
  20. #include <typeinfo>
  21. #include <typeindex>
  22. #include <memory>
  23. #include <functional>
  24. #include <sstream>
  25. #include <vector>
  26. #include <utility>
  27. #include "utils/overload.h"
  28. #include "utils/log_adapter.h"
  29. #include "utils/misc.h"
  30. namespace mindspore {
  31. // usage:AnyPtr sp = std::make_shared<Any>(aname);
  32. template <class T>
  33. std::string type(const T &t) {
  34. return demangle(typeid(t).name());
  35. }
  36. class Any {
  37. public:
  38. // constructors
  39. Any() : m_ptr(nullptr), m_tpIndex(std::type_index(typeid(void))) {}
  40. Any(const Any &other) : m_ptr(other.clone()), m_tpIndex(other.m_tpIndex) {}
  41. Any(Any &&other) : m_ptr(std::move(other.m_ptr)), m_tpIndex(std::move(other.m_tpIndex)) {}
  42. Any &operator=(Any &&other);
  43. // right reference constructor
  44. template <class T, class = typename std::enable_if<!std::is_same<typename std::decay<T>::type, Any>::value, T>::type>
  45. Any(T &&t) : m_tpIndex(typeid(typename std::decay<T>::type)) { // NOLINT
  46. BasePtr new_val(new Derived<typename std::decay<T>::type>(std::forward<T>(t)));
  47. std::swap(m_ptr, new_val);
  48. }
  49. ~Any() = default;
  50. // judge whether is empty
  51. bool empty() const { return m_ptr == nullptr; }
  52. // judge the is relation
  53. template <class T>
  54. bool is() const {
  55. return m_tpIndex == std::type_index(typeid(T));
  56. }
  57. const std::type_info &type() const { return m_ptr ? m_ptr->type() : typeid(void); }
  58. std::size_t Hash() const {
  59. std::stringstream buffer;
  60. buffer << m_tpIndex.name();
  61. if (m_ptr != nullptr) {
  62. buffer << m_ptr->GetString();
  63. }
  64. return std::hash<std::string>()(buffer.str());
  65. }
  66. template <typename T>
  67. bool Apply(const std::function<void(T &)> &fn) {
  68. if (type() == typeid(T)) {
  69. T x = cast<T>();
  70. fn(x);
  71. return true;
  72. }
  73. return false;
  74. }
  75. std::string GetString() const {
  76. if (m_ptr != nullptr) {
  77. return m_ptr->GetString();
  78. } else {
  79. return std::string("");
  80. }
  81. }
  82. friend std::ostream &operator<<(std::ostream &os, const Any &any) {
  83. os << any.GetString();
  84. return os;
  85. }
  86. // type cast
  87. template <class T>
  88. T &cast() const {
  89. if (!is<T>() || !m_ptr) {
  90. // Use MS_LOGFATAL replace throw std::bad_cast()
  91. MS_LOG(EXCEPTION) << "can not cast " << m_tpIndex.name() << " to " << typeid(T).name();
  92. }
  93. auto ptr = static_cast<Derived<T> *>(m_ptr.get());
  94. return ptr->m_value;
  95. }
  96. bool operator==(const Any &other) const {
  97. if (m_tpIndex != other.m_tpIndex) {
  98. return false;
  99. }
  100. if (m_ptr == nullptr && other.m_ptr == nullptr) {
  101. return true;
  102. }
  103. if (m_ptr == nullptr || other.m_ptr == nullptr) {
  104. return false;
  105. }
  106. return *m_ptr == *other.m_ptr;
  107. }
  108. bool operator!=(const Any &other) const { return !(operator==(other)); }
  109. Any &operator=(const Any &other);
  110. bool operator<(const Any &other) const;
  111. std::string ToString() const {
  112. std::ostringstream buffer;
  113. if (m_tpIndex == typeid(float)) {
  114. buffer << "<float> " << cast<float>();
  115. } else if (m_tpIndex == typeid(double)) {
  116. buffer << "<double> " << cast<double>();
  117. } else if (m_tpIndex == typeid(int)) {
  118. buffer << "<int> " << cast<int>();
  119. } else if (m_tpIndex == typeid(bool)) {
  120. buffer << "<bool> " << cast<bool>();
  121. } else {
  122. buffer << "<" << demangle(m_tpIndex.name()) << "> " << m_ptr->GetString();
  123. }
  124. return buffer.str();
  125. }
  126. __attribute__((used)) void dump() const { std::cout << ToString() << std::endl; }
  127. private:
  128. struct Base;
  129. using BasePtr = std::unique_ptr<Base>;
  130. // type base definition
  131. struct Base {
  132. virtual const std::type_info &type() const = 0;
  133. virtual BasePtr clone() const = 0;
  134. virtual ~Base() = default;
  135. virtual bool operator==(const Base &other) const = 0;
  136. virtual std::string GetString() = 0;
  137. };
  138. template <typename T>
  139. struct Derived : public Base {
  140. template <typename... Args>
  141. explicit Derived(Args &&... args) : m_value(std::forward<Args>(args)...), serialize_cache_("") {}
  142. bool operator==(const Base &other) const override {
  143. if (typeid(*this) != typeid(other)) {
  144. return false;
  145. }
  146. return m_value == static_cast<const Derived<T> &>(other).m_value;
  147. }
  148. const std::type_info &type() const override { return typeid(T); }
  149. BasePtr clone() const override { return BasePtr(new Derived<T>(m_value)); }
  150. ~Derived() override {}
  151. std::string GetString() override {
  152. std::stringstream buffer;
  153. buffer << m_value;
  154. return buffer.str();
  155. }
  156. T m_value;
  157. std::string serialize_cache_;
  158. };
  159. // clone method
  160. BasePtr clone() const {
  161. if (m_ptr != nullptr) {
  162. return m_ptr->clone();
  163. }
  164. return nullptr;
  165. }
  166. BasePtr m_ptr; // point to real data
  167. std::type_index m_tpIndex; // type info of data
  168. };
  169. using AnyPtr = std::shared_ptr<Any>;
  170. struct AnyHash {
  171. std::size_t operator()(const Any &c) const { return c.Hash(); }
  172. };
  173. struct AnyLess {
  174. bool operator()(const Any &a, const Any &b) const { return a.Hash() < b.Hash(); }
  175. };
  176. bool AnyIsLiteral(const Any &any);
  177. } // namespace mindspore
  178. #endif // MINDSPORE_CORE_UTILS_ANY_H_