// 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_GTYPE_TRAITS_HPP #define OPENCV_GAPI_GTYPE_TRAITS_HPP #include #include #include #include #include #include #include namespace cv { namespace detail { // FIXME: These traits and enum and possible numerous switch(kind) // block may be replaced with a special Handler object or with // a double dispatch enum class ArgKind: int { OPAQUE, // Unknown, generic, opaque-to-GAPI data type - STATIC GOBJREF, // reference to object GMAT, // a cv::GMat GSCALAR, // a cv::GScalar GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray!) }; // Describe G-API types (G-types) with traits. Mostly used by // cv::GArg to store meta information about types passed into // operation arguments. Please note that cv::GComputation is // defined on GProtoArgs, not GArgs! template struct GTypeTraits; template struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::OPAQUE; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GMAT; static constexpr const GShape shape = GShape::GMAT; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GSCALAR; static constexpr const GShape shape = GShape::GSCALAR; }; template struct GTypeTraits > { static constexpr const ArgKind kind = ArgKind::GARRAY; static constexpr const GShape shape = GShape::GARRAY; using host_type = std::vector; using strip_type = cv::detail::VectorRef; static cv::detail::GArrayU wrap_value(const cv::GArray &t) { return t.strip();} static cv::detail::VectorRef wrap_in (const std::vector &t) { return detail::VectorRef(t); } static cv::detail::VectorRef wrap_out ( std::vector &t) { return detail::VectorRef(t); } }; // Tests if Trait for type T requires extra marshalling ("custom wrap") or not. // If Traits has wrap_value() defined, it does. template struct has_custom_wrap { template class check; template static std::true_type test(check::wrap_value)> *); template static std::false_type test(...); using type = decltype(test(nullptr)); static const constexpr bool value = std::is_same(nullptr))>::value; }; // Resolve a Host type back to its associated G-Type. // FIXME: Probably it can be avoided template struct GTypeOf; #if !defined(GAPI_STANDALONE) template<> struct GTypeOf { using type = cv::GMat; }; template<> struct GTypeOf { using type = cv::GScalar; }; #endif // !defined(GAPI_STANDALONE) template<> struct GTypeOf { using type = cv::GMat; }; template<> struct GTypeOf { using type = cv::GScalar; }; template struct GTypeOf > { using type = cv::GArray; }; template using g_type_of_t = typename GTypeOf::type; // Marshalling helper for G-types and its Host types. Helps G-API // to store G types in internal generic containers for further // processing. Implements the following callbacks: // // * wrap() - converts user-facing G-type into an internal one // for internal storage. // Used when G-API operation is instantiated (G::on(), // etc) during expressing a pipeline. Mostly returns input // value "as is" except the case when G-type is a template. For // template G-classes, calls custom wrap() from Traits. // The value returned by wrap() is then wrapped into GArg() and // stored in G-API metadata. // // Example: // - cv::GMat arguments are passed as-is. // - integers, pointers, STL containers, user types are passed as-is. // - cv::GArray is converted to cv::GArrayU. // // * wrap_in() / wrap_out() - convert Host type associated with // G-type to internal representation type. // // - For "simple" (non-template) G-types, returns value as-is. // Example: cv::GMat has host type cv::Mat, when user passes a // cv::Mat, system stores it internally as cv::Mat. // // - For "complex" (template) G-types, utilizes custom // wrap_in()/wrap_out() as described in Traits. // Example: cv::GArray has host type std::vector, when // user passes a std::vector, system stores it // internally as VectorRef (with stripped away). template struct WrapValue { static auto wrap(const T& t) -> typename std::remove_reference::type { return static_cast::type>(t); } template static U wrap_in (const U &u) { return u; } template static U* wrap_out(U &u) { return &u; } }; template struct WrapValue::value>::type> { static auto wrap(const T& t) -> decltype(GTypeTraits::wrap_value(t)) { return GTypeTraits::wrap_value(t); } template static auto wrap_in (const U &u) -> typename GTypeTraits::strip_type { return GTypeTraits::wrap_in(u); } template static auto wrap_out(U &u) -> typename GTypeTraits::strip_type { return GTypeTraits::wrap_out(u); } }; template using wrap_gapi_helper = WrapValue::type>; template using wrap_host_helper = WrapValue >::type>; } // namespace detail } // namespace cv #endif // OPENCV_GAPI_GTYPE_TRAITS_HPP