Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / gtyped.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_GTYPED_HPP
9 #define OPENCV_GAPI_GTYPED_HPP
10 #if !defined(GAPI_STANDALONE)
11
12 #include <vector>
13
14 #include "opencv2/gapi/gcomputation.hpp"
15 #include "opencv2/gapi/gcompiled.hpp"
16 #include "opencv2/gapi/gproto.hpp"
17 #include "opencv2/gapi/gcommon.hpp"
18
19 namespace cv {
20
21 namespace detail
22 {
23     // FIXME: How to prevent coolhackers from extending it by their own types?
24     // FIXME: ...Should we care?
25     template<typename T> struct ProtoToParam;
26     template<> struct ProtoToParam<cv::GMat>    { using type = cv::Mat; };
27     template<> struct ProtoToParam<cv::GScalar> { using type = cv::Scalar; };
28     template<typename U> struct ProtoToParam<cv::GArray<U> > { using type = std::vector<U>; };
29     template<typename T> using ProtoToParamT = typename ProtoToParam<T>::type;
30
31     template<typename T> struct ProtoToMeta;
32     template<> struct ProtoToMeta<cv::GMat>     { using type = cv::GMatDesc; };
33     template<> struct ProtoToMeta<cv::GScalar>  { using type = cv::GScalarDesc; };
34     template<typename U> struct ProtoToMeta<cv::GArray<U> > { using type = cv::GArrayDesc; };
35     template<typename T> using ProtoToMetaT = typename ProtoToMeta<T>::type;
36
37     //workaround for MSVC 19.0 bug
38     template <typename T>
39     auto make_default()->decltype(T{}) {return {};}
40 }; // detail
41
42 template<typename> class GComputationT;
43
44 // Single return value implementation
45 template<typename R, typename... Args> class GComputationT<R(Args...)>
46 {
47 public:
48     typedef std::function<R(Args...)> Gen;
49
50     class GCompiledT
51     {
52     private:
53         friend class GComputationT<R(Args...)>;
54
55         cv::GCompiled m_comp;
56
57         explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {}
58
59     public:
60         GCompiledT() {}
61
62         void operator()(detail::ProtoToParamT<Args>... inArgs,
63                         detail::ProtoToParamT<R> &outArg)
64         {
65             m_comp(cv::gin(inArgs...), cv::gout(outArg));
66         }
67
68         explicit operator bool() const
69         {
70             return static_cast<bool>(m_comp);
71         }
72     };
73
74 private:
75     typedef std::pair<R, GProtoInputArgs > Captured;
76
77     Captured capture(const Gen& g, Args... args)
78     {
79         return Captured(g(args...), cv::GIn(args...));
80     }
81
82     Captured m_capture;
83     cv::GComputation m_comp;
84
85 public:
86     GComputationT(const Gen &generator)
87         : m_capture(capture(generator, detail::make_default<Args>()...))
88         , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)),
89                  cv::GOut(m_capture.first))
90     {
91     }
92
93     void apply(detail::ProtoToParamT<Args>... inArgs,
94                detail::ProtoToParamT<R> &outArg)
95     {
96         m_comp.apply(cv::gin(inArgs...), cv::gout(outArg));
97     }
98
99     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
100     {
101         GMetaArgs inMetas = { GMetaArg(inDescs)... };
102         return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs()));
103     }
104
105     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs, GCompileArgs &&args)
106     {
107         GMetaArgs inMetas = { GMetaArg(inDescs)... };
108         return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args)));
109     }
110 };
111
112 // Multiple (fixed) return value implementation. FIXME: How to avoid copy-paste?
113 template<typename... R, typename... Args> class GComputationT<std::tuple<R...>(Args...)>
114 {
115 public:
116     typedef std::function<std::tuple<R...>(Args...)> Gen;
117
118     class GCompiledT
119     {
120     private:
121         friend class GComputationT<std::tuple<R...>(Args...)>;
122
123         cv::GCompiled m_comp;
124         explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {}
125
126     public:
127         GCompiledT() {}
128
129         void operator()(detail::ProtoToParamT<Args>... inArgs,
130                         detail::ProtoToParamT<R>&... outArgs)
131         {
132             m_comp(cv::gin(inArgs...), cv::gout(outArgs...));
133         }
134
135         explicit operator bool() const
136         {
137             return static_cast<bool>(m_comp);
138         }
139     };
140
141 private:
142     typedef std::pair<GProtoArgs, GProtoArgs> Captured;
143
144     template<int... IIs>
145     Captured capture(GProtoArgs &&args, const std::tuple<R...> &rr, detail::Seq<IIs...>)
146     {
147         return Captured(cv::GOut(std::get<IIs>(rr)...).m_args, args);
148     }
149
150     Captured capture(const Gen& g, Args... args)
151     {
152         return capture(cv::GIn(args...).m_args, g(args...), typename detail::MkSeq<sizeof...(R)>::type());
153     }
154
155     Captured m_capture;
156     cv::GComputation m_comp;
157
158 public:
159     GComputationT(const Gen &generator)
160         : m_capture(capture(generator, detail::make_default<Args>()...))
161         , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)),
162                  cv::GProtoOutputArgs(std::move(m_capture.first)))
163     {
164     }
165
166     void apply(detail::ProtoToParamT<Args>... inArgs,
167                detail::ProtoToParamT<R>&... outArgs)
168     {
169         m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...));
170     }
171
172     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
173     {
174         GMetaArgs inMetas = { GMetaArg(inDescs)... };
175         return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs()));
176     }
177
178     GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs, GCompileArgs &&args)
179     {
180         GMetaArgs inMetas = { GMetaArg(inDescs)... };
181         return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args)));
182     }
183 };
184
185 } // namespace cv
186 #endif // !defined(GAPI_STANDALONE)
187 #endif // OPENCV_GAPI_GTYPED_HPP