Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / gtype_traits.hpp
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.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_GTYPE_TRAITS_HPP
9 #define OPENCV_GAPI_GTYPE_TRAITS_HPP
10
11 #include <vector>
12 #include <type_traits>
13
14 #include <opencv2/gapi/gmat.hpp>
15 #include <opencv2/gapi/gscalar.hpp>
16 #include <opencv2/gapi/garray.hpp>
17 #include <opencv2/gapi/gcommon.hpp>
18 #include <opencv2/gapi/own/convert.hpp>
19
20 namespace cv
21 {
22 namespace detail
23 {
24     // FIXME: These traits and enum and possible numerous switch(kind)
25     // block may be replaced with a special Handler<T> object or with
26     // a double dispatch
27     enum class ArgKind: int
28     {
29         OPAQUE,       // Unknown, generic, opaque-to-GAPI data type - STATIC
30         GOBJREF,      // <internal> reference to object
31         GMAT,         // a cv::GMat
32         GSCALAR,      // a cv::GScalar
33         GARRAY,       // a cv::GArrayU (note - exactly GArrayU, not GArray<T>!)
34     };
35
36     // Describe G-API types (G-types) with traits.  Mostly used by
37     // cv::GArg to store meta information about types passed into
38     // operation arguments. Please note that cv::GComputation is
39     // defined on GProtoArgs, not GArgs!
40     template<typename T> struct GTypeTraits;
41     template<typename T> struct GTypeTraits
42     {
43         static constexpr const ArgKind kind = ArgKind::OPAQUE;
44     };
45     template<>           struct GTypeTraits<cv::GMat>
46     {
47         static constexpr const ArgKind kind = ArgKind::GMAT;
48         static constexpr const GShape shape = GShape::GMAT;
49     };
50     template<>           struct GTypeTraits<cv::GScalar>
51     {
52         static constexpr const ArgKind kind = ArgKind::GSCALAR;
53         static constexpr const GShape shape = GShape::GSCALAR;
54     };
55     template<class T> struct GTypeTraits<cv::GArray<T> >
56     {
57         static constexpr const ArgKind kind = ArgKind::GARRAY;
58         static constexpr const GShape shape = GShape::GARRAY;
59         using host_type  = std::vector<T>;
60         using strip_type = cv::detail::VectorRef;
61         static cv::detail::GArrayU   wrap_value(const cv::GArray<T>  &t) { return t.strip();}
62         static cv::detail::VectorRef wrap_in   (const std::vector<T> &t) { return detail::VectorRef(t); }
63         static cv::detail::VectorRef wrap_out  (      std::vector<T> &t) { return detail::VectorRef(t); }
64     };
65
66     // Tests if Trait for type T requires extra marshalling ("custom wrap") or not.
67     // If Traits<T> has wrap_value() defined, it does.
68     template<class T> struct has_custom_wrap
69     {
70         template<class,class> class check;
71         template<typename C> static std::true_type  test(check<C, decltype(&GTypeTraits<C>::wrap_value)> *);
72         template<typename C> static std::false_type test(...);
73         using type = decltype(test<T>(nullptr));
74         static const constexpr bool value = std::is_same<std::true_type, decltype(test<T>(nullptr))>::value;
75     };
76
77     // Resolve a Host type back to its associated G-Type.
78     // FIXME: Probably it can be avoided
79     template<typename T> struct GTypeOf;
80 #if !defined(GAPI_STANDALONE)
81     template<>           struct GTypeOf<cv::Mat>               { using type = cv::GMat;      };
82     template<>           struct GTypeOf<cv::Scalar>            { using type = cv::GScalar;   };
83 #endif // !defined(GAPI_STANDALONE)
84     template<>           struct GTypeOf<cv::gapi::own::Mat>    { using type = cv::GMat;      };
85     template<>           struct GTypeOf<cv::gapi::own::Scalar> { using type = cv::GScalar;   };
86     template<typename U> struct GTypeOf<std::vector<U> >       { using type = cv::GArray<U>; };
87     template<class T> using g_type_of_t = typename GTypeOf<T>::type;
88
89     // Marshalling helper for G-types and its Host types. Helps G-API
90     // to store G types in internal generic containers for further
91     // processing. Implements the following callbacks:
92     //
93     // * wrap() - converts user-facing G-type into an internal one
94     //   for internal storage.
95     //   Used when G-API operation is instantiated (G<Kernel>::on(),
96     //   etc) during expressing a pipeline. Mostly returns input
97     //   value "as is" except the case when G-type is a template. For
98     //   template G-classes, calls custom wrap() from Traits.
99     //   The value returned by wrap() is then wrapped into GArg() and
100     //   stored in G-API metadata.
101     //
102     //   Example:
103     //   - cv::GMat arguments are passed as-is.
104     //   - integers, pointers, STL containers, user types are passed as-is.
105     //   - cv::GArray<T> is converted to cv::GArrayU.
106     //
107     // * wrap_in() / wrap_out() - convert Host type associated with
108     //   G-type to internal representation type.
109     //
110     //   - For "simple" (non-template) G-types, returns value as-is.
111     //     Example: cv::GMat has host type cv::Mat, when user passes a
112     //              cv::Mat, system stores it internally as cv::Mat.
113     //
114     //   - For "complex" (template) G-types, utilizes custom
115     //     wrap_in()/wrap_out() as described in Traits.
116     //     Example: cv::GArray<T> has host type std::vector<T>, when
117     //              user passes a std::vector<T>, system stores it
118     //              internally as VectorRef (with <T> stripped away).
119     template<typename T, class Custom = void> struct WrapValue
120     {
121         static auto wrap(const T& t) ->
122             typename std::remove_reference<T>::type
123         {
124             return static_cast<typename std::remove_reference<T>::type>(t);
125         }
126
127         template<typename U> static U  wrap_in (const U &u) { return  u;  }
128         template<typename U> static U* wrap_out(U &u)       { return &u;  }
129     };
130     template<typename T> struct WrapValue<T, typename std::enable_if<has_custom_wrap<T>::value>::type>
131     {
132         static auto wrap(const T& t) -> decltype(GTypeTraits<T>::wrap_value(t))
133         {
134             return GTypeTraits<T>::wrap_value(t);
135         }
136         template<typename U> static auto wrap_in (const U &u) -> typename GTypeTraits<T>::strip_type
137         {
138             return GTypeTraits<T>::wrap_in(u);
139         }
140         template<typename U> static auto wrap_out(U &u) -> typename GTypeTraits<T>::strip_type
141         {
142             return GTypeTraits<T>::wrap_out(u);
143         }
144     };
145
146     template<typename T> using wrap_gapi_helper = WrapValue<typename std::decay<T>::type>;
147     template<typename T> using wrap_host_helper = WrapValue<typename std::decay<g_type_of_t<T> >::type>;
148
149 } // namespace detail
150 } // namespace cv
151
152 #endif // OPENCV_GAPI_GTYPE_TRAITS_HPP