|
- /**
- * Copyright 2019-2020 Huawei Technologies Co., Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef MINDSPORE_CORE_UTILS_ANY_H_
- #define MINDSPORE_CORE_UTILS_ANY_H_
-
- #include <iostream>
- #include <string>
- #include <typeinfo>
- #include <typeindex>
- #include <memory>
- #include <functional>
- #include <sstream>
- #include <vector>
- #include <utility>
-
- #include "utils/overload.h"
- #include "utils/log_adapter.h"
- #include "utils/misc.h"
-
- namespace mindspore {
- // usage:AnyPtr sp = std::make_shared<Any>(aname);
- template <class T>
- std::string type(const T &t) {
- return demangle(typeid(t).name());
- }
-
- class Any {
- public:
- // constructors
- Any() : m_ptr(nullptr), m_tpIndex(std::type_index(typeid(void))) {}
- Any(const Any &other) : m_ptr(other.clone()), m_tpIndex(other.m_tpIndex) {}
- Any(Any &&other) : m_ptr(std::move(other.m_ptr)), m_tpIndex(std::move(other.m_tpIndex)) {}
-
- Any &operator=(Any &&other);
- // right reference constructor
- template <class T, class = typename std::enable_if<!std::is_same<typename std::decay<T>::type, Any>::value, T>::type>
- Any(T &&t) : m_tpIndex(typeid(typename std::decay<T>::type)) { // NOLINT
- BasePtr new_val(new Derived<typename std::decay<T>::type>(std::forward<T>(t)));
- std::swap(m_ptr, new_val);
- }
-
- ~Any() = default;
-
- // judge whether is empty
- bool empty() const { return m_ptr == nullptr; }
-
- // judge the is relation
- template <class T>
- bool is() const {
- return m_tpIndex == std::type_index(typeid(T));
- }
-
- const std::type_info &type() const { return m_ptr ? m_ptr->type() : typeid(void); }
-
- std::size_t Hash() const {
- std::stringstream buffer;
- buffer << m_tpIndex.name();
- if (m_ptr != nullptr) {
- buffer << m_ptr->GetString();
- }
- return std::hash<std::string>()(buffer.str());
- }
-
- template <typename T>
- bool Apply(const std::function<void(T &)> &fn) {
- if (type() == typeid(T)) {
- T x = cast<T>();
- fn(x);
- return true;
- }
- return false;
- }
-
- std::string GetString() const {
- if (m_ptr != nullptr) {
- return m_ptr->GetString();
- } else {
- return std::string("");
- }
- }
-
- friend std::ostream &operator<<(std::ostream &os, const Any &any) {
- os << any.GetString();
- return os;
- }
-
- // type cast
- template <class T>
- T &cast() const {
- if (!is<T>() || !m_ptr) {
- // Use MS_LOGFATAL replace throw std::bad_cast()
- MS_LOG(EXCEPTION) << "can not cast " << m_tpIndex.name() << " to " << typeid(T).name();
- }
- auto ptr = static_cast<Derived<T> *>(m_ptr.get());
- return ptr->m_value;
- }
-
- bool operator==(const Any &other) const {
- if (m_tpIndex != other.m_tpIndex) {
- return false;
- }
- if (m_ptr == nullptr && other.m_ptr == nullptr) {
- return true;
- }
- if (m_ptr == nullptr || other.m_ptr == nullptr) {
- return false;
- }
- return *m_ptr == *other.m_ptr;
- }
-
- bool operator!=(const Any &other) const { return !(operator==(other)); }
-
- Any &operator=(const Any &other);
-
- bool operator<(const Any &other) const;
-
- std::string ToString() const {
- std::ostringstream buffer;
- if (m_tpIndex == typeid(float)) {
- buffer << "<float> " << cast<float>();
- } else if (m_tpIndex == typeid(double)) {
- buffer << "<double> " << cast<double>();
- } else if (m_tpIndex == typeid(int)) {
- buffer << "<int> " << cast<int>();
- } else if (m_tpIndex == typeid(bool)) {
- buffer << "<bool> " << cast<bool>();
- } else {
- buffer << "<" << demangle(m_tpIndex.name()) << "> " << m_ptr->GetString();
- }
- return buffer.str();
- }
- __attribute__((used)) void dump() const { std::cout << ToString() << std::endl; }
-
- private:
- struct Base;
- using BasePtr = std::unique_ptr<Base>;
-
- // type base definition
- struct Base {
- virtual const std::type_info &type() const = 0;
- virtual BasePtr clone() const = 0;
- virtual ~Base() = default;
- virtual bool operator==(const Base &other) const = 0;
- virtual std::string GetString() = 0;
- };
-
- template <typename T>
- struct Derived : public Base {
- template <typename... Args>
- explicit Derived(Args &&... args) : m_value(std::forward<Args>(args)...), serialize_cache_("") {}
-
- bool operator==(const Base &other) const override {
- if (typeid(*this) != typeid(other)) {
- return false;
- }
- return m_value == static_cast<const Derived<T> &>(other).m_value;
- }
-
- const std::type_info &type() const override { return typeid(T); }
-
- BasePtr clone() const override { return BasePtr(new Derived<T>(m_value)); }
-
- ~Derived() override {}
-
- std::string GetString() override {
- std::stringstream buffer;
- buffer << m_value;
- return buffer.str();
- }
-
- T m_value;
- std::string serialize_cache_;
- };
-
- // clone method
- BasePtr clone() const {
- if (m_ptr != nullptr) {
- return m_ptr->clone();
- }
- return nullptr;
- }
-
- BasePtr m_ptr; // point to real data
- std::type_index m_tpIndex; // type info of data
- };
-
- using AnyPtr = std::shared_ptr<Any>;
-
- struct AnyHash {
- std::size_t operator()(const Any &c) const { return c.Hash(); }
- };
-
- struct AnyLess {
- bool operator()(const Any &a, const Any &b) const { return a.Hash() < b.Hash(); }
- };
-
- bool AnyIsLiteral(const Any &any);
- } // namespace mindspore
-
- #endif // MINDSPORE_CORE_UTILS_ANY_H_
|