// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // // Copyright (C) 2018 Intel Corporation #ifndef OPENCV_GAPI_GTYPED_HPP #define OPENCV_GAPI_GTYPED_HPP #if !defined(GAPI_STANDALONE) #include #include "opencv2/gapi/gcomputation.hpp" #include "opencv2/gapi/gcompiled.hpp" #include "opencv2/gapi/gproto.hpp" #include "opencv2/gapi/gcommon.hpp" namespace cv { namespace detail { // FIXME: How to prevent coolhackers from extending it by their own types? // FIXME: ...Should we care? template struct ProtoToParam; template<> struct ProtoToParam { using type = cv::Mat; }; template<> struct ProtoToParam { using type = cv::Scalar; }; template struct ProtoToParam > { using type = std::vector; }; template using ProtoToParamT = typename ProtoToParam::type; template struct ProtoToMeta; template<> struct ProtoToMeta { using type = cv::GMatDesc; }; template<> struct ProtoToMeta { using type = cv::GScalarDesc; }; template struct ProtoToMeta > { using type = cv::GArrayDesc; }; template using ProtoToMetaT = typename ProtoToMeta::type; //workaround for MSVC 19.0 bug template auto make_default()->decltype(T{}) {return {};} }; // detail template class GComputationT; // Single return value implementation template class GComputationT { public: typedef std::function Gen; class GCompiledT { private: friend class GComputationT; cv::GCompiled m_comp; explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {} public: GCompiledT() {} void operator()(detail::ProtoToParamT... inArgs, detail::ProtoToParamT &outArg) { m_comp(cv::gin(inArgs...), cv::gout(outArg)); } explicit operator bool() const { return static_cast(m_comp); } }; private: typedef std::pair Captured; Captured capture(const Gen& g, Args... args) { return Captured(g(args...), cv::GIn(args...)); } Captured m_capture; cv::GComputation m_comp; public: GComputationT(const Gen &generator) : m_capture(capture(generator, detail::make_default()...)) , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)), cv::GOut(m_capture.first)) { } void apply(detail::ProtoToParamT... inArgs, detail::ProtoToParamT &outArg) { m_comp.apply(cv::gin(inArgs...), cv::gout(outArg)); } GCompiledT compile(detail::ProtoToMetaT... inDescs) { GMetaArgs inMetas = { GMetaArg(inDescs)... }; return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs())); } GCompiledT compile(detail::ProtoToMetaT... inDescs, GCompileArgs &&args) { GMetaArgs inMetas = { GMetaArg(inDescs)... }; return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args))); } }; // Multiple (fixed) return value implementation. FIXME: How to avoid copy-paste? template class GComputationT(Args...)> { public: typedef std::function(Args...)> Gen; class GCompiledT { private: friend class GComputationT(Args...)>; cv::GCompiled m_comp; explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {} public: GCompiledT() {} void operator()(detail::ProtoToParamT... inArgs, detail::ProtoToParamT&... outArgs) { m_comp(cv::gin(inArgs...), cv::gout(outArgs...)); } explicit operator bool() const { return static_cast(m_comp); } }; private: typedef std::pair Captured; template Captured capture(GProtoArgs &&args, const std::tuple &rr, detail::Seq) { return Captured(cv::GOut(std::get(rr)...).m_args, args); } Captured capture(const Gen& g, Args... args) { return capture(cv::GIn(args...).m_args, g(args...), typename detail::MkSeq::type()); } Captured m_capture; cv::GComputation m_comp; public: GComputationT(const Gen &generator) : m_capture(capture(generator, detail::make_default()...)) , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)), cv::GProtoOutputArgs(std::move(m_capture.first))) { } void apply(detail::ProtoToParamT... inArgs, detail::ProtoToParamT&... outArgs) { m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...)); } GCompiledT compile(detail::ProtoToMetaT... inDescs) { GMetaArgs inMetas = { GMetaArg(inDescs)... }; return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs())); } GCompiledT compile(detail::ProtoToMetaT... inDescs, GCompileArgs &&args) { GMetaArgs inMetas = { GMetaArg(inDescs)... }; return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args))); } }; } // namespace cv #endif // !defined(GAPI_STANDALONE) #endif // OPENCV_GAPI_GTYPED_HPP