#pragma once #include namespace cv { namespace dnn { struct DictValue { int type; union { int i; unsigned u; double d; bool b; String *s; }; DictValue(const DictValue &r); DictValue(int p = 0) : type(cv::Param::INT), i(p) {} DictValue(unsigned p) : type(cv::Param::UNSIGNED_INT), u(p) {} DictValue(double p) : type(cv::Param::REAL), d(p) {} DictValue(bool p) : type(cv::Param::BOOLEAN), b(p) {} DictValue(const String &p) : type(cv::Param::STRING), s(new String(p)) {} template T get() const; template const T &get() const; DictValue &operator=(const DictValue &r); ~DictValue(); private: void release(); }; class Dict { //TODO: maybe this mechanism was realized somewhere in OpenCV? typedef std::map _Dict; _Dict dict; public: template const T &get(const String &name) const { _Dict::const_iterator i = dict.find(name); CV_Assert(i != dict.end()); return i->second.get(); } template const T &get(const String &name, const T &default) const { _Dict::const_iterator i = dict.find(name); if (i != dict.end()) return i->second.get(); else return default; } template const T &set(const String &name, const T &value) { _Dict::iterator i = dict.find(name); if (i != dict.end()) i->second = DictValue(value); else dict.insert(std::make_pair(name, DictValue(value))); return value; } }; template<> inline int DictValue::get() const { CV_Assert(type == cv::ParamType::type || type == cv::ParamType::type && (int)u >= 0); return i; } template<> inline unsigned DictValue::get() const { CV_Assert(type == cv::ParamType::type || type == cv::ParamType::type && i >= 0); return u; } template<> inline double DictValue::get() const { CV_Assert(type == cv::ParamType::type); return d; } template<> inline float DictValue::get() const { CV_Assert(type == cv::ParamType::type); return (float)d; } template<> inline bool DictValue::get() const { if (type == cv::ParamType::type) { return b; } else if (type == cv::ParamType::type || type == cv::ParamType::type) { return i; } else { CV_Assert(type == cv::ParamType::type || type == cv::ParamType::type || type == cv::ParamType::type); return 0; } } template<> inline const String &DictValue::get() const { CV_Assert(type == cv::ParamType::type); return *s; } inline void DictValue::release() { if (type == cv::Param::STRING && s != NULL) { delete s; s = NULL; } } inline DictValue::~DictValue() { release(); } inline DictValue & DictValue::operator=(const DictValue &r) { if (&r == this) return *this; release(); //how to copy anonymous union without memcpy? for (size_t i = 0; i < sizeof(*this); i++) ((uchar*)this)[i] = ((uchar*)&r)[i]; if (r.type == cv::Param::STRING) { s = new String(*r.s); } return *this; } inline DictValue::DictValue(const DictValue &r) { *this = r; } } }