// 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 <vector>
|
|
#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<typename T> struct ProtoToParam;
|
template<> struct ProtoToParam<cv::GMat> { using type = cv::Mat; };
|
template<> struct ProtoToParam<cv::GScalar> { using type = cv::Scalar; };
|
template<typename U> struct ProtoToParam<cv::GArray<U> > { using type = std::vector<U>; };
|
template<typename T> using ProtoToParamT = typename ProtoToParam<T>::type;
|
|
template<typename T> struct ProtoToMeta;
|
template<> struct ProtoToMeta<cv::GMat> { using type = cv::GMatDesc; };
|
template<> struct ProtoToMeta<cv::GScalar> { using type = cv::GScalarDesc; };
|
template<typename U> struct ProtoToMeta<cv::GArray<U> > { using type = cv::GArrayDesc; };
|
template<typename T> using ProtoToMetaT = typename ProtoToMeta<T>::type;
|
|
//workaround for MSVC 19.0 bug
|
template <typename T>
|
auto make_default()->decltype(T{}) {return {};}
|
}; // detail
|
|
template<typename> class GComputationT;
|
|
// Single return value implementation
|
template<typename R, typename... Args> class GComputationT<R(Args...)>
|
{
|
public:
|
typedef std::function<R(Args...)> Gen;
|
|
class GCompiledT
|
{
|
private:
|
friend class GComputationT<R(Args...)>;
|
|
cv::GCompiled m_comp;
|
|
explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {}
|
|
public:
|
GCompiledT() {}
|
|
void operator()(detail::ProtoToParamT<Args>... inArgs,
|
detail::ProtoToParamT<R> &outArg)
|
{
|
m_comp(cv::gin(inArgs...), cv::gout(outArg));
|
}
|
|
explicit operator bool() const
|
{
|
return static_cast<bool>(m_comp);
|
}
|
};
|
|
private:
|
typedef std::pair<R, GProtoInputArgs > 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<Args>()...))
|
, m_comp(cv::GProtoInputArgs(std::move(m_capture.second)),
|
cv::GOut(m_capture.first))
|
{
|
}
|
|
void apply(detail::ProtoToParamT<Args>... inArgs,
|
detail::ProtoToParamT<R> &outArg)
|
{
|
m_comp.apply(cv::gin(inArgs...), cv::gout(outArg));
|
}
|
|
GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
|
{
|
GMetaArgs inMetas = { GMetaArg(inDescs)... };
|
return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs()));
|
}
|
|
GCompiledT compile(detail::ProtoToMetaT<Args>... 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<typename... R, typename... Args> class GComputationT<std::tuple<R...>(Args...)>
|
{
|
public:
|
typedef std::function<std::tuple<R...>(Args...)> Gen;
|
|
class GCompiledT
|
{
|
private:
|
friend class GComputationT<std::tuple<R...>(Args...)>;
|
|
cv::GCompiled m_comp;
|
explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {}
|
|
public:
|
GCompiledT() {}
|
|
void operator()(detail::ProtoToParamT<Args>... inArgs,
|
detail::ProtoToParamT<R>&... outArgs)
|
{
|
m_comp(cv::gin(inArgs...), cv::gout(outArgs...));
|
}
|
|
explicit operator bool() const
|
{
|
return static_cast<bool>(m_comp);
|
}
|
};
|
|
private:
|
typedef std::pair<GProtoArgs, GProtoArgs> Captured;
|
|
template<int... IIs>
|
Captured capture(GProtoArgs &&args, const std::tuple<R...> &rr, detail::Seq<IIs...>)
|
{
|
return Captured(cv::GOut(std::get<IIs>(rr)...).m_args, args);
|
}
|
|
Captured capture(const Gen& g, Args... args)
|
{
|
return capture(cv::GIn(args...).m_args, g(args...), typename detail::MkSeq<sizeof...(R)>::type());
|
}
|
|
Captured m_capture;
|
cv::GComputation m_comp;
|
|
public:
|
GComputationT(const Gen &generator)
|
: m_capture(capture(generator, detail::make_default<Args>()...))
|
, m_comp(cv::GProtoInputArgs(std::move(m_capture.second)),
|
cv::GProtoOutputArgs(std::move(m_capture.first)))
|
{
|
}
|
|
void apply(detail::ProtoToParamT<Args>... inArgs,
|
detail::ProtoToParamT<R>&... outArgs)
|
{
|
m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...));
|
}
|
|
GCompiledT compile(detail::ProtoToMetaT<Args>... inDescs)
|
{
|
GMetaArgs inMetas = { GMetaArg(inDescs)... };
|
return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs()));
|
}
|
|
GCompiledT compile(detail::ProtoToMetaT<Args>... 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
|