1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
5 // Copyright (C) 2018-2020 Intel Corporation
8 #ifndef OPENCV_GAPI_GTYPE_TRAITS_HPP
9 #define OPENCV_GAPI_GTYPE_TRAITS_HPP
12 #include <type_traits>
14 #include <opencv2/gapi/gmat.hpp>
15 #include <opencv2/gapi/gscalar.hpp>
16 #include <opencv2/gapi/garray.hpp>
17 #include <opencv2/gapi/gopaque.hpp>
18 #include <opencv2/gapi/gframe.hpp>
19 #include <opencv2/gapi/streaming/source.hpp>
20 #include <opencv2/gapi/media.hpp>
21 #include <opencv2/gapi/gcommon.hpp>
27 // FIXME: These traits and enum and possible numerous switch(kind)
28 // block may be replaced with a special Handler<T> object or with
30 enum class ArgKind: int
32 OPAQUE_VAL, // Unknown, generic, opaque-to-GAPI data type - STATIC
33 // Note: OPAQUE is sometimes defined in Win sys headers
34 #if !defined(OPAQUE) && !defined(CV_DOXYGEN)
35 OPAQUE = OPAQUE_VAL, // deprecated value used for compatibility, use OPAQUE_VAL instead
37 GOBJREF, // <internal> reference to object
40 GFRAME, // a cv::GFrame
41 GSCALAR, // a cv::GScalar
42 GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray<T>!)
43 GOPAQUE, // a cv::GOpaqueU (note - exactly GOpaqueU, not GOpaque<T>!)
47 constexpr const char* meta_to_string() noexcept;
49 constexpr const char* meta_to_string<cv::GMatDesc>() noexcept { return "GMatDesc"; }
51 constexpr const char* meta_to_string<cv::GScalarDesc>() noexcept { return "GScalarDesc"; }
53 constexpr const char* meta_to_string<cv::GArrayDesc>() noexcept { return "GArrayDesc"; }
55 constexpr const char* meta_to_string<cv::GOpaqueDesc>() noexcept { return "GOpaqueDesc"; }
57 constexpr const char* meta_to_string<cv::GFrameDesc>() noexcept { return "GFrameDesc";}
59 // Describe G-API types (G-types) with traits. Mostly used by
60 // cv::GArg to store meta information about types passed into
61 // operation arguments. Please note that cv::GComputation is
62 // defined on GProtoArgs, not GArgs!
63 template<typename T> struct GTypeTraits;
64 template<typename T> struct GTypeTraits
66 static constexpr const ArgKind kind = ArgKind::OPAQUE_VAL;
67 static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
69 template<> struct GTypeTraits<cv::GMat>
71 static constexpr const ArgKind kind = ArgKind::GMAT;
72 static constexpr const GShape shape = GShape::GMAT;
73 static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
75 template<> struct GTypeTraits<cv::GMatP>
77 static constexpr const ArgKind kind = ArgKind::GMATP;
78 static constexpr const GShape shape = GShape::GMAT;
79 static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
81 template<> struct GTypeTraits<cv::GFrame>
83 static constexpr const ArgKind kind = ArgKind::GFRAME;
84 static constexpr const GShape shape = GShape::GFRAME;
85 static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
87 template<> struct GTypeTraits<cv::GScalar>
89 static constexpr const ArgKind kind = ArgKind::GSCALAR;
90 static constexpr const GShape shape = GShape::GSCALAR;
91 static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN;
93 template<class T> struct GTypeTraits<cv::GArray<T> >
95 static constexpr const ArgKind kind = ArgKind::GARRAY;
96 static constexpr const GShape shape = GShape::GARRAY;
97 static constexpr const OpaqueKind op_kind = GOpaqueTraits<T>::kind;
98 using host_type = std::vector<T>;
99 using strip_type = cv::detail::VectorRef;
100 static cv::detail::GArrayU wrap_value(const cv::GArray<T> &t) { return t.strip();}
101 static cv::detail::VectorRef wrap_in (const std::vector<T> &t) { return detail::VectorRef(t); }
102 static cv::detail::VectorRef wrap_out ( std::vector<T> &t) { return detail::VectorRef(t); }
104 template<class T> struct GTypeTraits<cv::GOpaque<T> >
106 static constexpr const ArgKind kind = ArgKind::GOPAQUE;
107 static constexpr const GShape shape = GShape::GOPAQUE;
108 static constexpr const OpaqueKind op_kind = GOpaqueTraits<T>::kind;
110 using strip_type = cv::detail::OpaqueRef;
111 static cv::detail::GOpaqueU wrap_value(const cv::GOpaque<T> &t) { return t.strip();}
112 static cv::detail::OpaqueRef wrap_in (const T &t) { return detail::OpaqueRef(t); }
113 static cv::detail::OpaqueRef wrap_out ( T &t) { return detail::OpaqueRef(t); }
116 // Tests if Trait for type T requires extra marshalling ("custom wrap") or not.
117 // If Traits<T> has wrap_value() defined, it does.
118 template<class T> struct has_custom_wrap
120 template<class,class> class check;
121 template<typename C> static std::true_type test(check<C, decltype(>ypeTraits<C>::wrap_value)> *);
122 template<typename C> static std::false_type test(...);
123 using type = decltype(test<T>(nullptr));
124 static const constexpr bool value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
127 // Resolve a Host type back to its associated G-Type.
128 // FIXME: Probably it can be avoided
129 // FIXME: GMatP is not present here.
130 // (Actually these traits is used only to check
131 // if associated G-type has custom wrap functions
132 // and GMat behavior is correct for GMatP)
133 template<typename T> struct GTypeOf;
134 #if !defined(GAPI_STANDALONE)
135 template<> struct GTypeOf<cv::UMat> { using type = cv::GMat; };
136 #endif // !defined(GAPI_STANDALONE)
137 template<> struct GTypeOf<cv::Mat> { using type = cv::GMat; };
138 template<> struct GTypeOf<cv::RMat> { using type = cv::GMat; };
139 template<> struct GTypeOf<cv::Scalar> { using type = cv::GScalar; };
140 template<typename U> struct GTypeOf<std::vector<U> > { using type = cv::GArray<U>; };
141 template<typename U> struct GTypeOf { using type = cv::GOpaque<U>;};
142 template<> struct GTypeOf<cv::MediaFrame> { using type = cv::GFrame; };
143 // FIXME: This is not quite correct since IStreamSource may produce not only Mat but also Scalar
144 // and vector data. TODO: Extend the type dispatching on these types too.
145 template<> struct GTypeOf<cv::gapi::wip::IStreamSource::Ptr> { using type = cv::GMat;};
146 template<class T> using g_type_of_t = typename GTypeOf<T>::type;
148 // Marshalling helper for G-types and its Host types. Helps G-API
149 // to store G types in internal generic containers for further
150 // processing. Implements the following callbacks:
152 // * wrap() - converts user-facing G-type into an internal one
153 // for internal storage.
154 // Used when G-API operation is instantiated (G<Kernel>::on(),
155 // etc) during expressing a pipeline. Mostly returns input
156 // value "as is" except the case when G-type is a template. For
157 // template G-classes, calls custom wrap() from Traits.
158 // The value returned by wrap() is then wrapped into GArg() and
159 // stored in G-API metadata.
162 // - cv::GMat arguments are passed as-is.
163 // - integers, pointers, STL containers, user types are passed as-is.
164 // - cv::GArray<T> is converted to cv::GArrayU.
166 // * wrap_in() / wrap_out() - convert Host type associated with
167 // G-type to internal representation type.
169 // - For "simple" (non-template) G-types, returns value as-is.
170 // Example: cv::GMat has host type cv::Mat, when user passes a
171 // cv::Mat, system stores it internally as cv::Mat.
173 // - For "complex" (template) G-types, utilizes custom
174 // wrap_in()/wrap_out() as described in Traits.
175 // Example: cv::GArray<T> has host type std::vector<T>, when
176 // user passes a std::vector<T>, system stores it
177 // internally as VectorRef (with <T> stripped away).
178 template<typename T, class Custom = void> struct WrapValue
180 static auto wrap(const T& t) ->
181 typename std::remove_reference<T>::type
183 return static_cast<typename std::remove_reference<T>::type>(t);
186 template<typename U> static U wrap_in (const U &u) { return u; }
187 template<typename U> static U* wrap_out(U &u) { return &u; }
189 template<typename T> struct WrapValue<T, typename std::enable_if<has_custom_wrap<T>::value>::type>
191 static auto wrap(const T& t) -> decltype(GTypeTraits<T>::wrap_value(t))
193 return GTypeTraits<T>::wrap_value(t);
195 template<typename U> static auto wrap_in (const U &u) -> typename GTypeTraits<T>::strip_type
197 return GTypeTraits<T>::wrap_in(u);
199 template<typename U> static auto wrap_out(U &u) -> typename GTypeTraits<T>::strip_type
201 return GTypeTraits<T>::wrap_out(u);
205 template<typename T> using wrap_gapi_helper = WrapValue<typename std::decay<T>::type>;
206 template<typename T> using wrap_host_helper = WrapValue<typename std::decay<g_type_of_t<T> >::type>;
208 // Union type for various user-defined type constructors (GArray<T>,
211 // TODO: Replace construct-only API with a more generic one (probably
212 // with bits of introspection)
214 // Not required for non-user-defined types (GMat, GScalar, etc)
215 using HostCtor = util::variant
217 , detail::ConstructVec
218 , detail::ConstructOpaque
221 template<typename T> struct GObtainCtor {
222 static HostCtor get() { return HostCtor{}; }
224 template<typename T> struct GObtainCtor<GArray<T> > {
225 static HostCtor get() { return HostCtor{ConstructVec{&GArray<T>::VCtor}}; };
227 template<typename T> struct GObtainCtor<GOpaque<T> > {
228 static HostCtor get() { return HostCtor{ConstructOpaque{&GOpaque<T>::Ctor}}; };
230 } // namespace detail
233 #endif // OPENCV_GAPI_GTYPE_TRAITS_HPP