1009 lines
32 KiB
C++
1009 lines
32 KiB
C++
// Copyright (C) 2018-2025 Intel Corporation
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
/**
|
|
* @brief A header file for the Any class
|
|
* @file openvino/runtime/any.hpp
|
|
*/
|
|
#pragma once
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <string>
|
|
#include <typeindex>
|
|
#include <typeinfo>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
|
|
#include "openvino/core/attribute_visitor.hpp"
|
|
#include "openvino/core/except.hpp"
|
|
#include "openvino/core/runtime_attribute.hpp"
|
|
|
|
namespace ov {
|
|
class Plugin;
|
|
/** @cond INTERNAL */
|
|
class Any;
|
|
|
|
using AnyMap = std::map<std::string, Any>;
|
|
|
|
namespace util {
|
|
|
|
OPENVINO_API bool equal(std::type_index lhs, std::type_index rhs);
|
|
|
|
template <typename T, typename = void>
|
|
struct Read;
|
|
|
|
template <class T>
|
|
struct Readable {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::declval<Read<U>>()(std::declval<std::istream&>(), std::declval<U&>()),
|
|
std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
template <class T>
|
|
struct Istreamable {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::declval<std::istream&>() >> std::declval<U&>(), std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<bool> {
|
|
void operator()(std::istream& is, bool& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<Any> {
|
|
void operator()(std::istream& is, Any& any) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<int> {
|
|
void operator()(std::istream& is, int& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<long> {
|
|
void operator()(std::istream& is, long& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<long long> {
|
|
void operator()(std::istream& is, long long& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<unsigned> {
|
|
void operator()(std::istream& is, unsigned& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<unsigned long> {
|
|
void operator()(std::istream& is, unsigned long& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<unsigned long long> {
|
|
void operator()(std::istream& is, unsigned long long& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<float> {
|
|
void operator()(std::istream& is, float& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<double> {
|
|
void operator()(std::istream& is, double& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<long double> {
|
|
void operator()(std::istream& is, long double& value) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<std::tuple<unsigned int, unsigned int, unsigned int>> {
|
|
void operator()(std::istream& is, std::tuple<unsigned int, unsigned int, unsigned int>& tuple) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<std::tuple<unsigned int, unsigned int>> {
|
|
void operator()(std::istream& is, std::tuple<unsigned int, unsigned int>& tuple) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Read<AnyMap> {
|
|
void operator()(std::istream& is, AnyMap& map) const;
|
|
};
|
|
|
|
template <typename T>
|
|
auto from_string(const std::string& str) -> const
|
|
typename std::enable_if<std::is_same<T, std::string>::value, T>::type& {
|
|
return str;
|
|
}
|
|
|
|
template <typename T>
|
|
auto from_string(const std::string& val) ->
|
|
typename std::enable_if<Readable<T>::value && !std::is_same<T, std::string>::value, T>::type {
|
|
std::stringstream ss(val);
|
|
T value;
|
|
Read<T>{}(ss, value);
|
|
return value;
|
|
}
|
|
|
|
template <typename T>
|
|
auto from_string(const std::string& val) ->
|
|
typename std::enable_if<!Readable<T>::value && Istreamable<T>::value && !std::is_same<T, std::string>::value,
|
|
T>::type {
|
|
std::stringstream ss(val);
|
|
T value;
|
|
ss >> value;
|
|
return value;
|
|
}
|
|
|
|
template <class T>
|
|
struct ValueTyped {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::declval<typename U::value_type&>(), std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
|
|
template <typename T,
|
|
typename std::enable_if<ValueTyped<T>::value && Readable<typename T::value_type>::value, bool>::type = true>
|
|
typename T::value_type from_string(const std::string& val, const T&) {
|
|
std::stringstream ss(val);
|
|
typename T::value_type value;
|
|
Read<typename T::value_type, void>{}(ss, value);
|
|
return value;
|
|
}
|
|
|
|
template <typename T,
|
|
typename std::enable_if<ValueTyped<T>::value && !Readable<typename T::value_type>::value &&
|
|
Istreamable<typename T::value_type>::value,
|
|
bool>::type = true>
|
|
typename T::value_type from_string(const std::string& val, const T&) {
|
|
std::stringstream ss(val);
|
|
typename T::value_type value;
|
|
ss >> value;
|
|
return value;
|
|
}
|
|
|
|
template <typename T>
|
|
auto from_string(const std::string& val) ->
|
|
typename std::enable_if<!Readable<T>::value && !Istreamable<T>::value && !std::is_same<T, std::string>::value,
|
|
T>::type {
|
|
OPENVINO_THROW("Could read type without std::istream& operator>>(std::istream&, T)",
|
|
" defined or ov::util::Read<T> class specialization, T: ",
|
|
typeid(T).name());
|
|
}
|
|
|
|
template <typename T, typename A>
|
|
struct Read<std::vector<T, A>, typename std::enable_if<std::is_default_constructible<T>::value>::type> {
|
|
void operator()(std::istream& is, std::vector<T, A>& vec) const {
|
|
while (is.good()) {
|
|
std::string str;
|
|
is >> str;
|
|
auto v = from_string<T>(str);
|
|
vec.push_back(std::move(v));
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename K, typename C, typename A>
|
|
struct Read<std::set<K, C, A>, typename std::enable_if<std::is_default_constructible<K>::value>::type> {
|
|
void operator()(std::istream& is, std::set<K, C, A>& set) const {
|
|
while (is.good()) {
|
|
std::string str;
|
|
is >> str;
|
|
auto v = from_string<K>(str);
|
|
set.insert(std::move(v));
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename K, typename T, typename C, typename A>
|
|
struct Read<
|
|
std::map<K, T, C, A>,
|
|
typename std::enable_if<std::is_default_constructible<K>::value && std::is_default_constructible<T>::value>::type> {
|
|
void operator()(std::istream& is, std::map<K, T, C, A>& map) const {
|
|
char c;
|
|
|
|
is >> c;
|
|
OPENVINO_ASSERT(c == '{', "Failed to parse std::map<K, T>. Starting symbols is not '{', it's ", c);
|
|
|
|
while (c != '}') {
|
|
std::string key, value;
|
|
std::getline(is, key, ':');
|
|
size_t enclosed_container_level = 0;
|
|
|
|
while (is.good()) {
|
|
is >> c;
|
|
if (c == ',') { // delimiter between map's pairs
|
|
if (enclosed_container_level == 0) // we should interrupt after delimiter
|
|
break;
|
|
}
|
|
if (c == '{' || c == '[') // case of enclosed maps / arrays
|
|
++enclosed_container_level;
|
|
if (c == '}' || c == ']') {
|
|
if (enclosed_container_level == 0)
|
|
break; // end of map
|
|
--enclosed_container_level;
|
|
}
|
|
|
|
value += c; // accumulate current value
|
|
}
|
|
map.emplace(from_string<K>(key), from_string<T>(value));
|
|
}
|
|
|
|
OPENVINO_ASSERT(c == '}', "Failed to parse std::map<K, T>. Ending symbols is not '}', it's ", c);
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct Write;
|
|
|
|
template <class T>
|
|
struct Ostreamable {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::declval<std::ostream&>() << std::declval<U>(), std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
|
|
template <class T>
|
|
struct Writable {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::declval<Write<U>>()(std::declval<std::ostream&>(), std::declval<const U&>()),
|
|
std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Write<bool> {
|
|
void operator()(std::ostream& is, const bool& b) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Write<Any> {
|
|
void operator()(std::ostream& is, const Any& any) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Write<std::tuple<unsigned int, unsigned int, unsigned int>> {
|
|
void operator()(std::ostream& os, const std::tuple<unsigned int, unsigned int, unsigned int>& tuple) const;
|
|
};
|
|
|
|
template <>
|
|
struct OPENVINO_API Write<std::tuple<unsigned int, unsigned int>> {
|
|
void operator()(std::ostream& os, const std::tuple<unsigned int, unsigned int>& tuple) const;
|
|
};
|
|
|
|
template <typename T>
|
|
auto to_string(const T& str) -> const typename std::enable_if<std::is_same<T, std::string>::value, T>::type& {
|
|
return str;
|
|
}
|
|
|
|
template <typename T>
|
|
auto to_string(const T& value) ->
|
|
typename std::enable_if<Writable<T>::value && !std::is_same<T, std::string>::value, std::string>::type {
|
|
std::stringstream ss;
|
|
Write<T>{}(ss, value);
|
|
return ss.str();
|
|
}
|
|
|
|
template <typename T>
|
|
auto to_string(const T& value) ->
|
|
typename std::enable_if<!Writable<T>::value && Ostreamable<T>::value && !std::is_same<T, std::string>::value,
|
|
std::string>::type {
|
|
std::stringstream ss;
|
|
ss << value;
|
|
return ss.str();
|
|
}
|
|
|
|
template <typename T>
|
|
auto to_string(const T&) ->
|
|
typename std::enable_if<!Writable<T>::value && !Ostreamable<T>::value && !std::is_same<T, std::string>::value,
|
|
std::string>::type {
|
|
OPENVINO_THROW("Could convert to string from type without std::ostream& operator>>(std::ostream&, const T&)",
|
|
" defined or ov::util::Write<T> class specialization, T: ",
|
|
typeid(T).name());
|
|
}
|
|
|
|
template <typename T, typename A>
|
|
struct Write<std::vector<T, A>> {
|
|
void operator()(std::ostream& os, const std::vector<T, A>& vec) const {
|
|
if (!vec.empty()) {
|
|
std::size_t i = 0;
|
|
for (auto&& v : vec) {
|
|
os << to_string(v);
|
|
if (i < (vec.size() - 1))
|
|
os << ' ';
|
|
++i;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename K, typename C, typename A>
|
|
struct Write<std::set<K, C, A>> {
|
|
void operator()(std::ostream& os, const std::set<K, C, A>& set) const {
|
|
if (!set.empty()) {
|
|
std::size_t i = 0;
|
|
for (auto&& v : set) {
|
|
os << to_string(v);
|
|
if (i < (set.size() - 1))
|
|
os << ' ';
|
|
++i;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename K, typename T, typename C, typename A>
|
|
struct Write<std::map<K, T, C, A>> {
|
|
void operator()(std::ostream& os, const std::map<K, T, C, A>& map) const {
|
|
if (!map.empty()) {
|
|
std::size_t i = 0;
|
|
os << '{';
|
|
for (auto&& v : map) {
|
|
os << to_string(v.first) << ':' << to_string(v.second);
|
|
if (i < (map.size() - 1))
|
|
os << ',';
|
|
++i;
|
|
}
|
|
os << '}';
|
|
}
|
|
}
|
|
};
|
|
} // namespace util
|
|
/** @endcond */
|
|
|
|
class Node;
|
|
class RuntimeAttribute;
|
|
|
|
class CompiledModel;
|
|
namespace proxy {
|
|
|
|
class CompiledModel;
|
|
|
|
}
|
|
class RemoteContext;
|
|
class RemoteTensor;
|
|
|
|
/**
|
|
* @brief This class represents an object to work with different types
|
|
*/
|
|
class OPENVINO_API Any {
|
|
std::shared_ptr<void> _so;
|
|
|
|
template <typename T>
|
|
using decay_t = typename std::decay<T>::type;
|
|
|
|
template <typename T>
|
|
struct EqualityComparable {
|
|
static void* conv(bool);
|
|
template <typename U>
|
|
static char test(decltype(conv(std::declval<U>() == std::declval<U>())));
|
|
template <typename U>
|
|
static long test(...);
|
|
constexpr static const bool value = sizeof(test<T>(nullptr)) == sizeof(char);
|
|
};
|
|
|
|
template <typename... T>
|
|
struct EqualityComparable<std::map<T...>> {
|
|
static void* conv(bool);
|
|
template <typename U>
|
|
static char test(decltype(conv(std::declval<typename U::key_type>() == std::declval<typename U::key_type>() &&
|
|
std::declval<typename U::mapped_type>() ==
|
|
std::declval<typename U::mapped_type>())));
|
|
template <typename U>
|
|
static long test(...);
|
|
constexpr static const bool value = sizeof(test<std::map<T...>>(nullptr)) == sizeof(char);
|
|
};
|
|
|
|
template <typename... T>
|
|
struct EqualityComparable<std::vector<T...>> {
|
|
static void* conv(bool);
|
|
template <typename U>
|
|
static char test(decltype(conv(std::declval<typename U::value_type>() ==
|
|
std::declval<typename U::value_type>())));
|
|
template <typename U>
|
|
static long test(...);
|
|
constexpr static const bool value = sizeof(test<std::vector<T...>>(nullptr)) == sizeof(char);
|
|
};
|
|
|
|
template <class U>
|
|
static typename std::enable_if<EqualityComparable<U>::value, bool>::type equal_impl(const U& rhs, const U& lhs) {
|
|
return rhs == lhs;
|
|
}
|
|
|
|
template <class U>
|
|
[[noreturn]] static typename std::enable_if<!EqualityComparable<U>::value, bool>::type equal_impl(const U&,
|
|
const U&) {
|
|
OPENVINO_THROW("Could not compare types without equality operator");
|
|
}
|
|
|
|
template <typename T>
|
|
struct HasBaseMemberType {
|
|
template <class U>
|
|
static auto test(U*) -> decltype(std::is_class<typename U::Base>::value, std::true_type()) {
|
|
return {};
|
|
}
|
|
template <typename>
|
|
static auto test(...) -> std::false_type {
|
|
return {};
|
|
}
|
|
constexpr static const auto value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
|
|
};
|
|
|
|
template <typename>
|
|
struct TupleToTypeIndex;
|
|
|
|
template <typename... Args>
|
|
struct TupleToTypeIndex<std::tuple<Args...>> {
|
|
static std::vector<std::type_index> get() {
|
|
return {typeid(Args)...};
|
|
}
|
|
};
|
|
|
|
class OPENVINO_API Base : public std::enable_shared_from_this<Base> {
|
|
public:
|
|
void type_check(const std::type_info&) const;
|
|
|
|
using Ptr = std::shared_ptr<Base>;
|
|
virtual const std::type_info& type_info() const = 0;
|
|
virtual std::vector<std::type_index> base_type_info() const = 0;
|
|
bool is_base_type_info(const std::type_info& type_info) const;
|
|
virtual const void* addressof() const = 0;
|
|
void* addressof() {
|
|
return const_cast<void*>(const_cast<const Base*>(this)->addressof());
|
|
}
|
|
virtual Base::Ptr copy() const = 0;
|
|
virtual bool equal(const Base& rhs) const = 0;
|
|
virtual void print(std::ostream& os) const = 0;
|
|
virtual void read(std::istream& os) = 0;
|
|
void read_to(Base& other) const;
|
|
|
|
virtual const DiscreteTypeInfo& get_type_info() const = 0;
|
|
virtual std::shared_ptr<RuntimeAttribute> as_runtime_attribute() const;
|
|
virtual bool is_copyable() const;
|
|
virtual Any init(const std::shared_ptr<Node>& node);
|
|
virtual Any merge(const std::vector<std::shared_ptr<Node>>& nodes);
|
|
virtual std::string to_string();
|
|
virtual bool visit_attributes(AttributeVisitor&);
|
|
bool visit_attributes(AttributeVisitor&) const;
|
|
std::string to_string() const;
|
|
|
|
bool is(const std::type_info& other) const;
|
|
bool is_signed_integral() const;
|
|
bool is_unsigned_integral() const;
|
|
bool is_floating_point() const;
|
|
|
|
template <class T>
|
|
bool is() const {
|
|
return is(typeid(decay_t<T>));
|
|
}
|
|
|
|
template <class T>
|
|
T& as() & {
|
|
return *static_cast<decay_t<T>*>(addressof());
|
|
}
|
|
|
|
template <class T>
|
|
const T& as() const& {
|
|
return *static_cast<const decay_t<T>*>(addressof());
|
|
}
|
|
|
|
template <class T>
|
|
T convert() const;
|
|
|
|
protected:
|
|
template <class U>
|
|
[[noreturn]] U convert_impl() const;
|
|
|
|
template <class U, class T, class... Others>
|
|
U convert_impl() const;
|
|
|
|
virtual ~Base();
|
|
};
|
|
|
|
template <class T, typename = void>
|
|
struct Impl;
|
|
template <class T>
|
|
struct Impl<T, typename std::enable_if<std::is_convertible<T, std::shared_ptr<RuntimeAttribute>>::value>::type>
|
|
: public Base {
|
|
const DiscreteTypeInfo& get_type_info() const override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->get_type_info();
|
|
}
|
|
std::shared_ptr<RuntimeAttribute> as_runtime_attribute() const override {
|
|
return std::static_pointer_cast<RuntimeAttribute>(runtime_attribute);
|
|
}
|
|
bool is_copyable() const override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->is_copyable();
|
|
}
|
|
Any init(const std::shared_ptr<Node>& node) override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->init(node);
|
|
}
|
|
Any merge(const std::vector<std::shared_ptr<Node>>& nodes) override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->merge(nodes);
|
|
}
|
|
std::string to_string() override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->to_string();
|
|
}
|
|
|
|
bool visit_attributes(AttributeVisitor& visitor) override {
|
|
return static_cast<RuntimeAttribute*>(runtime_attribute.get())->visit_attributes(visitor);
|
|
}
|
|
|
|
Impl(const T& runtime_attribute) : runtime_attribute{runtime_attribute} {}
|
|
|
|
const std::type_info& type_info() const override {
|
|
return typeid(T);
|
|
}
|
|
|
|
std::vector<std::type_index> base_type_info() const override {
|
|
return {typeid(std::shared_ptr<RuntimeAttribute>)};
|
|
}
|
|
|
|
const void* addressof() const override {
|
|
return std::addressof(runtime_attribute);
|
|
}
|
|
|
|
Base::Ptr copy() const override {
|
|
return std::make_shared<Impl<T>>(this->runtime_attribute);
|
|
}
|
|
|
|
bool equal(const Base& rhs) const override {
|
|
if (rhs.is<T>()) {
|
|
return equal_impl(this->runtime_attribute, rhs.as<T>());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void print(std::ostream& os) const override {
|
|
os << runtime_attribute->to_string();
|
|
}
|
|
|
|
void read(std::istream&) override {
|
|
OPENVINO_THROW("Pointer to runtime attribute is not readable from std::istream");
|
|
}
|
|
|
|
T runtime_attribute;
|
|
};
|
|
|
|
template <class T>
|
|
struct Impl<T, typename std::enable_if<!std::is_convertible<T, std::shared_ptr<RuntimeAttribute>>::value>::type>
|
|
: public Base {
|
|
OPENVINO_RTTI(typeid(T).name());
|
|
|
|
template <typename... Args>
|
|
Impl(Args&&... args) : value(std::forward<Args>(args)...) {}
|
|
|
|
const std::type_info& type_info() const override {
|
|
return typeid(T);
|
|
}
|
|
|
|
const void* addressof() const override {
|
|
return std::addressof(value);
|
|
}
|
|
|
|
Base::Ptr copy() const override {
|
|
return std::make_shared<Impl<T>>(this->value);
|
|
}
|
|
|
|
template <class U>
|
|
static std::vector<std::type_index> base_type_info_impl(
|
|
typename std::enable_if<HasBaseMemberType<U>::value, std::true_type>::type = {}) {
|
|
return TupleToTypeIndex<typename T::Base>::get();
|
|
}
|
|
template <class U>
|
|
static std::vector<std::type_index> base_type_info_impl(
|
|
typename std::enable_if<!HasBaseMemberType<U>::value, std::false_type>::type = {}) {
|
|
return {typeid(T)};
|
|
}
|
|
|
|
std::vector<std::type_index> base_type_info() const override {
|
|
return base_type_info_impl<T>();
|
|
}
|
|
|
|
bool equal(const Base& rhs) const override {
|
|
if (rhs.is<T>()) {
|
|
return equal_impl(this->value, rhs.as<T>());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<util::Writable<U>::value>::type print_impl(std::ostream& os, const U& value) {
|
|
util::Write<U>{}(os, value);
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<!util::Writable<U>::value && util::Ostreamable<U>::value>::type print_impl(
|
|
std::ostream& os,
|
|
const U& value) {
|
|
os << value;
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<!util::Writable<U>::value && !util::Ostreamable<U>::value>::type print_impl(
|
|
std::ostream&,
|
|
const U&) {}
|
|
|
|
void print(std::ostream& os) const override {
|
|
print_impl(os, value);
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<util::Readable<U>::value>::type read_impl(std::istream& is, U& value) {
|
|
util::Read<U>{}(is, value);
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<!util::Readable<U>::value && util::Istreamable<U>::value>::type read_impl(
|
|
std::istream& is,
|
|
U& value) {
|
|
is >> value;
|
|
}
|
|
|
|
template <typename U>
|
|
static typename std::enable_if<!util::Readable<U>::value && !util::Istreamable<U>::value>::type read_impl(
|
|
std::istream&,
|
|
U&) {
|
|
OPENVINO_THROW("Could read type without std::istream& operator>>(std::istream&, T)",
|
|
" defined or ov::util::Read<T> class specialization, T: ",
|
|
typeid(T).name());
|
|
}
|
|
|
|
void read(std::istream& is) override {
|
|
read_impl(is, value);
|
|
}
|
|
|
|
T value;
|
|
};
|
|
|
|
// Generic if there is no specialization for T.
|
|
template <class T>
|
|
T& as_impl(...) {
|
|
impl_check();
|
|
if (is<T>()) {
|
|
return _impl->as<T>();
|
|
}
|
|
|
|
OPENVINO_THROW("Bad as from: ", _impl->type_info().name(), " to: ", typeid(T).name());
|
|
}
|
|
|
|
template <class T, typename std::enable_if<std::is_same<T, std::string>::value>::type* = nullptr>
|
|
T& as_impl(int) {
|
|
if (_impl != nullptr) {
|
|
if (_impl->is<T>()) {
|
|
return _impl->as<T>();
|
|
} else {
|
|
_temp = std::make_shared<Impl<std::string>>();
|
|
_impl->read_to(*_temp);
|
|
return _temp->as<std::string>();
|
|
}
|
|
} else {
|
|
_temp = std::make_shared<Impl<std::string>>();
|
|
return _temp->as<std::string>();
|
|
}
|
|
}
|
|
|
|
template <
|
|
class T,
|
|
typename std::enable_if<std::is_convertible<T, std::shared_ptr<RuntimeAttribute>>::value>::type* = nullptr>
|
|
T& as_impl(int) {
|
|
if (_impl == nullptr) {
|
|
_temp = std::make_shared<Impl<decay_t<T>>>(T{});
|
|
return _temp->as<T>();
|
|
} else {
|
|
if (_impl->is<T>()) {
|
|
return _impl->as<T>();
|
|
} else {
|
|
auto runtime_attribute = _impl->as_runtime_attribute();
|
|
if (runtime_attribute == nullptr) {
|
|
OPENVINO_THROW("Any does not contains pointer to runtime_attribute. It contains ",
|
|
_impl->type_info().name());
|
|
}
|
|
auto vptr = ov::as_type_ptr<typename T::element_type>(runtime_attribute);
|
|
if (vptr == nullptr && T::element_type::get_type_info_static() != runtime_attribute->get_type_info() &&
|
|
T::element_type::get_type_info_static() != RuntimeAttribute::get_type_info_static()) {
|
|
OPENVINO_THROW("Could not as Any runtime_attribute to ",
|
|
typeid(T).name(),
|
|
" from ",
|
|
_impl->type_info().name(),
|
|
"; from ",
|
|
static_cast<std::string>(runtime_attribute->get_type_info()),
|
|
" to ",
|
|
static_cast<std::string>(T::element_type::get_type_info_static()));
|
|
}
|
|
_temp = std::make_shared<Impl<decay_t<T>>>(
|
|
std::static_pointer_cast<typename T::element_type>(runtime_attribute));
|
|
return _temp->as<T>();
|
|
}
|
|
}
|
|
}
|
|
|
|
template <class T,
|
|
typename std::enable_if<std::is_arithmetic<T>::value &&
|
|
!std::is_same<typename std::decay<T>::type, bool>::value>::type* = nullptr>
|
|
T& as_impl(int);
|
|
|
|
template <class T,
|
|
typename std::enable_if<
|
|
(util::Istreamable<T>::value || util::Readable<T>::value) && !std::is_same<T, std::string>::value &&
|
|
(!std::is_arithmetic<T>::value || std::is_same<typename std::decay<T>::type, bool>::value)>::type* =
|
|
nullptr>
|
|
T& as_impl(int) {
|
|
impl_check();
|
|
|
|
if (is<T>()) {
|
|
return _impl->as<T>();
|
|
} else if (_impl->is<std::string>()) {
|
|
_temp = std::make_shared<Impl<decay_t<T>>>();
|
|
_impl->read_to(*_temp);
|
|
return _temp->as<T>();
|
|
}
|
|
|
|
OPENVINO_THROW("Bad as from: ", _impl->type_info().name(), " to: ", typeid(T).name());
|
|
}
|
|
|
|
friend class ::ov::RuntimeAttribute;
|
|
friend class ::ov::CompiledModel;
|
|
friend class ::ov::proxy::CompiledModel;
|
|
friend class ::ov::RemoteContext;
|
|
friend class ::ov::RemoteTensor;
|
|
friend class ::ov::Plugin;
|
|
|
|
Any(const Any& other, const std::shared_ptr<void>& so);
|
|
|
|
void impl_check() const;
|
|
|
|
mutable Base::Ptr _temp;
|
|
|
|
Base::Ptr _impl;
|
|
|
|
public:
|
|
/// @brief Default constructor
|
|
Any() = default;
|
|
|
|
/// @brief Copy constructor
|
|
/// @param other other Any object
|
|
Any(const Any& other);
|
|
|
|
/// @brief Copy assignment operator
|
|
/// @param other other Any object
|
|
/// @return reference to the current object
|
|
Any& operator=(const Any& other);
|
|
|
|
/// @brief Default move constructor
|
|
/// @param other other Any object
|
|
Any(Any&& other) = default;
|
|
|
|
/// @brief Default move assignment operator
|
|
/// @param other other Any object
|
|
/// @return reference to the current object
|
|
Any& operator=(Any&& other) = default;
|
|
|
|
/**
|
|
* @brief Destructor preserves unloading order of implementation object and reference to library
|
|
*/
|
|
~Any();
|
|
|
|
/**
|
|
* @brief Constructor creates any with object
|
|
*
|
|
* @tparam T Any type
|
|
* @param value object
|
|
*/
|
|
template <typename T,
|
|
typename std::enable_if<!std::is_same<decay_t<T>, Any>::value && !std::is_abstract<decay_t<T>>::value &&
|
|
!std::is_convertible<decay_t<T>, Base::Ptr>::value,
|
|
bool>::type = true>
|
|
Any(T&& value) : _impl{std::make_shared<Impl<decay_t<T>>>(std::forward<T>(value))} {}
|
|
|
|
/**
|
|
* @brief Constructor creates string any from char *
|
|
*
|
|
* @param str char array
|
|
*/
|
|
Any(const char* str);
|
|
|
|
/**
|
|
* @brief Empty constructor
|
|
*
|
|
*/
|
|
Any(const std::nullptr_t);
|
|
|
|
/**
|
|
* @brief Inplace value construction function
|
|
*
|
|
* @tparam T Any type
|
|
* @tparam Args pack of parameter types passed to T constructor
|
|
* @param args pack of parameters passed to T constructor
|
|
*/
|
|
template <typename T, typename... Args>
|
|
static Any make(Args&&... args) {
|
|
Any any;
|
|
any._impl = std::make_shared<Impl<decay_t<T>>>(std::forward<Args>(args)...);
|
|
return any;
|
|
}
|
|
|
|
/**
|
|
* Returns type info
|
|
* @return type info
|
|
*/
|
|
const std::type_info& type_info() const;
|
|
|
|
/**
|
|
* Checks that any contains a value
|
|
* @return false if any contains a value else false
|
|
*/
|
|
bool empty() const;
|
|
|
|
/**
|
|
* @brief Check that stored type can be casted to specified type.
|
|
* If internal type supports Base
|
|
* @tparam T Type of value
|
|
* @return true if type of value is correct. Return false if any is empty
|
|
*/
|
|
template <class T>
|
|
bool is() const {
|
|
return _impl && (_impl->is<T>() || _impl->is_base_type_info(typeid(decay_t<T>)));
|
|
}
|
|
|
|
/**
|
|
* Dynamic as to specified type
|
|
* @tparam T type
|
|
* @return reference to caster object
|
|
*/
|
|
template <class T>
|
|
T& as() {
|
|
return as_impl<T>(int{});
|
|
}
|
|
|
|
/**
|
|
* Dynamic as to specified type
|
|
* @tparam T type
|
|
* @return const reference to caster object
|
|
*/
|
|
template <class T>
|
|
const T& as() const {
|
|
return const_cast<Any*>(this)->as<T>();
|
|
}
|
|
|
|
/**
|
|
* @brief The comparison operator for the Any
|
|
*
|
|
* @param other object to compare
|
|
* @return true if objects are equal
|
|
*/
|
|
bool operator==(const Any& other) const;
|
|
|
|
/**
|
|
* @brief The comparison operator for the Any
|
|
*
|
|
* @param other object to compare
|
|
* @return true if objects are equal
|
|
*/
|
|
bool operator==(const std::nullptr_t&) const;
|
|
|
|
/**
|
|
* @brief The comparison operator for the Any
|
|
*
|
|
* @param other object to compare
|
|
* @return true if objects aren't equal
|
|
*/
|
|
bool operator!=(const Any& other) const;
|
|
|
|
/**
|
|
* @brief Prints underlying object to the given output stream.
|
|
* Uses operator<< if it is defined, leaves stream unchanged otherwise.
|
|
* In case of empty any or nullptr stream immediately returns.
|
|
*
|
|
* @param stream Output stream object will be printed to.
|
|
*/
|
|
void print(std::ostream& stream) const;
|
|
|
|
/**
|
|
* @brief Read into underlying object from the given input stream.
|
|
* Uses operator>> if it is defined, leaves stream unchanged otherwise.
|
|
* In case of empty any or nullptr stream immediately returns.
|
|
*
|
|
* @param stream Output stream object will be printed to.
|
|
*/
|
|
void read(std::istream& stream);
|
|
|
|
/**
|
|
* @brief Returns address to internal value if any is not empty and `nullptr` instead
|
|
* @return address to internal stored value
|
|
*/
|
|
void* addressof();
|
|
|
|
/**
|
|
* @brief Returns address to internal value if any is not empty and `nullptr` instead
|
|
* @return address to internal stored value
|
|
*/
|
|
const void* addressof() const;
|
|
};
|
|
|
|
using RTMap = AnyMap;
|
|
|
|
using AnyVector = std::vector<ov::Any>;
|
|
|
|
/** @cond INTERNAL */
|
|
inline static void PrintTo(const Any& any, std::ostream* os) {
|
|
any.print(*os);
|
|
}
|
|
/** @endcond */
|
|
|
|
template <>
|
|
OPENVINO_API unsigned long long Any::Base::convert<unsigned long long>() const;
|
|
|
|
template <>
|
|
OPENVINO_API long long Any::Base::convert<long long>() const;
|
|
|
|
template <>
|
|
OPENVINO_API double Any::Base::convert<double>() const;
|
|
|
|
template <class T,
|
|
typename std::enable_if<std::is_arithmetic<T>::value &&
|
|
!std::is_same<typename std::decay<T>::type, bool>::value>::type*>
|
|
T& Any::as_impl(int) {
|
|
impl_check();
|
|
if (is<T>()) {
|
|
return _impl->as<T>();
|
|
} else if (util::Readable<T>::value && _impl->is<std::string>()) {
|
|
_temp = std::make_shared<Impl<decay_t<T>>>();
|
|
_impl->read_to(*_temp);
|
|
return _temp->as<T>();
|
|
} else if (_impl->is_signed_integral()) {
|
|
auto value = _impl->convert<long long>();
|
|
_temp = std::make_shared<Impl<decay_t<T>>>(static_cast<T>(value));
|
|
return _temp->as<T>();
|
|
} else if (_impl->is_unsigned_integral()) {
|
|
auto value = _impl->convert<unsigned long long>();
|
|
_temp = std::make_shared<Impl<decay_t<T>>>(static_cast<T>(value));
|
|
return _temp->as<T>();
|
|
} else if (_impl->is_floating_point()) {
|
|
auto value = _impl->convert<double>();
|
|
_temp = std::make_shared<Impl<decay_t<T>>>(static_cast<T>(value));
|
|
return _temp->as<T>();
|
|
}
|
|
|
|
OPENVINO_THROW("Bad as from: ", _impl->type_info().name(), " to: ", typeid(T).name());
|
|
}
|
|
} // namespace ov
|