1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Changed behaviour of cv::gapi::serialize, cv::gapi::deserialize for GCompileArgs

- cv::gapi::serialize bypasses compile arguments which have no S11N specialization with serialize/deserialize callbacks for underlying types
- cv::gapi::deserialize can accept arbitraty number of serialized compile args in a stream but will return only those which are requested by user via template parameter pack if they are presented in the stream. If some or all of them are not presented cv::gapi::deserialize will ignore and return only those which are presented
- cv::gapi::deserialize can accept only types which can be deserialized (have S11N<T> specialization with the user callbacks)
- Added cv::gapi::s11n::detail::has_S11N_spec<T> trait to separate compile arguments which have S11N<T> specialization with the user callbacks
This commit is contained in:
AsyaPronina
2020-11-02 18:54:19 +03:00
parent 691c3d1e3c
commit 48ccbe39b4
5 changed files with 310 additions and 45 deletions
@@ -161,7 +161,9 @@ public:
template<typename T, typename std::enable_if<!detail::is_compile_arg<T>::value, int>::type = 0>
explicit GCompileArg(T &&t)
: tag(detail::CompileArgTag<typename std::decay<T>::type>::tag())
, serializeF(&cv::gapi::s11n::detail::wrap_serialize<T>::serialize)
, serializeF(cv::gapi::s11n::detail::has_S11N_spec<T>::value ?
&cv::gapi::s11n::detail::wrap_serialize<T>::serialize :
nullptr)
, arg(t)
{
}
@@ -178,7 +180,10 @@ public:
void serialize(cv::gapi::s11n::IOStream& os) const
{
serializeF(os, *this);
if (serializeF)
{
serializeF(os, *this);
}
}
private:
@@ -222,8 +227,8 @@ template<typename T> struct wrap_serialize
{
static void serialize(IOStream& os, const GCompileArg& arg)
{
using decayed_type = typename std::decay<T>::type;
S11N<decayed_type>::serialize(os, arg.get<decayed_type>());
using DT = typename std::decay<T>::type;
S11N<DT>::serialize(os, arg.get<DT>());
}
};
} // namespace detail
+34 -14
View File
@@ -265,23 +265,25 @@ void getRunArgByIdx (IIStream& is, cv::util::variant<Ts...> &v, uint32_t idx) {
namespace detail
{
template<typename T> struct deserialize_arg;
template<typename T> struct try_deserialize_comparg;
template<> struct deserialize_arg<std::tuple<>> {
static GCompileArg exec(cv::gapi::s11n::IIStream&, const std::string&) {
throw std::logic_error("Passed arg can't be deserialized!");
template<> struct try_deserialize_comparg<std::tuple<>> {
static cv::util::optional<GCompileArg> exec(const std::string&, cv::gapi::s11n::IIStream&) {
return { };
}
};
template<typename T, typename... Types>
struct deserialize_arg<std::tuple<T, Types...>> {
static GCompileArg exec(cv::gapi::s11n::IIStream& is, const std::string& tag) {
struct try_deserialize_comparg<std::tuple<T, Types...>> {
static cv::util::optional<GCompileArg> exec(const std::string& tag, cv::gapi::s11n::IIStream& is) {
if (tag == cv::detail::CompileArgTag<T>::tag()) {
return GCompileArg {
cv::gapi::s11n::detail::S11N<T>::deserialize(is)
};
static_assert(cv::gapi::s11n::detail::has_S11N_spec<T>::value,
"cv::gapi::deserialize<GCompileArgs, Types...> expects Types to have S11N "
"specializations with deserialization callbacks!");
return cv::util::optional<GCompileArg>(
GCompileArg { cv::gapi::s11n::detail::S11N<T>::deserialize(is) });
}
return deserialize_arg<std::tuple<Types...>>::exec(is, tag);
return try_deserialize_comparg<std::tuple<Types...>>::exec(tag, is);
}
};
@@ -303,17 +305,35 @@ static GRunArg exec(cv::gapi::s11n::IIStream& is, uint32_t idx) {
};
template<typename... Types>
cv::GCompileArgs getCompileArgs(const std::vector<char> &p) {
std::unique_ptr<cv::gapi::s11n::IIStream> pIs = cv::gapi::s11n::detail::getInStream(p);
cv::gapi::s11n::IIStream& is = *pIs;
inline cv::util::optional<GCompileArg> tryDeserializeCompArg(const std::string& tag,
const std::vector<char>& sArg) {
std::unique_ptr<cv::gapi::s11n::IIStream> pArgIs = cv::gapi::s11n::detail::getInStream(sArg);
return try_deserialize_comparg<std::tuple<Types...>>::exec(tag, *pArgIs);
}
template<typename... Types>
cv::GCompileArgs getCompileArgs(const std::vector<char> &sArgs) {
cv::GCompileArgs args;
std::unique_ptr<cv::gapi::s11n::IIStream> pIs = cv::gapi::s11n::detail::getInStream(sArgs);
cv::gapi::s11n::IIStream& is = *pIs;
uint32_t sz = 0;
is >> sz;
for (uint32_t i = 0; i < sz; ++i) {
std::string tag;
is >> tag;
args.push_back(cv::gapi::detail::deserialize_arg<std::tuple<Types...>>::exec(is, tag));
std::vector<char> sArg;
is >> sArg;
cv::util::optional<GCompileArg> dArg =
cv::gapi::detail::tryDeserializeCompArg<Types...>(tag, sArg);
if (dArg.has_value())
{
args.push_back(dArg.value());
}
}
return args;
@@ -8,6 +8,7 @@
#define OPENCV_GAPI_S11N_BASE_HPP
#include <opencv2/gapi/own/assert.hpp>
#include <opencv2/gapi/own/exports.hpp>
namespace cv {
namespace gapi {
@@ -16,10 +17,14 @@ struct IOStream;
struct IIStream;
namespace detail {
// Will be used along with default types if possible in specific cases (compile args, etc)
// Note: actual implementation is defined by user
struct NotImplemented {
};
// The default S11N for custom types is NotImplemented
// Don't! sublass from NotImplemented if you actually implement S11N.
template<typename T>
struct S11N {
struct S11N: public NotImplemented {
static void serialize(IOStream &, const T &) {
GAPI_Assert(false && "No serialization routine is provided!");
}
@@ -28,6 +33,11 @@ struct S11N {
}
};
template<typename T> struct has_S11N_spec {
static constexpr bool value = !std::is_base_of<NotImplemented,
S11N<typename std::decay<T>::type>>::value;
};
} // namespace detail
} // namespace s11n
} // namespace gapi