添加项目文件。
This commit is contained in:
190
3rdparty/opencv/inc/opencv2/gapi/util/any.hpp
vendored
Normal file
190
3rdparty/opencv/inc/opencv2/gapi/util/any.hpp
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
// 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_UTIL_ANY_HPP
|
||||
#define OPENCV_GAPI_UTIL_ANY_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
#include <opencv2/gapi/util/throw.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// disable MSVC warning on "multiple copy constructors specified"
|
||||
# pragma warning(disable: 4521)
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
template <class T, class Source>
|
||||
T down_cast(Source operand)
|
||||
{
|
||||
#if defined(__GXX_RTTI) || defined(_CPPRTTI)
|
||||
return dynamic_cast<T>(operand);
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#warning used static cast instead of dynamic because RTTI is disabled
|
||||
#else
|
||||
#pragma message("WARNING: used static cast instead of dynamic because RTTI is disabled")
|
||||
#endif
|
||||
return static_cast<T>(operand);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace util
|
||||
{
|
||||
class bad_any_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
virtual const char* what() const noexcept override
|
||||
{
|
||||
return "Bad any cast";
|
||||
}
|
||||
};
|
||||
|
||||
//modeled against C++17 std::any
|
||||
|
||||
class any
|
||||
{
|
||||
private:
|
||||
struct holder;
|
||||
using holder_ptr = std::unique_ptr<holder>;
|
||||
struct holder
|
||||
{
|
||||
virtual holder_ptr clone() = 0;
|
||||
virtual ~holder() = default;
|
||||
};
|
||||
|
||||
template <typename value_t>
|
||||
struct holder_impl : holder
|
||||
{
|
||||
value_t v;
|
||||
template<typename arg_t>
|
||||
holder_impl(arg_t&& a) : v(std::forward<arg_t>(a)) {}
|
||||
holder_ptr clone() override { return holder_ptr(new holder_impl (v));}
|
||||
};
|
||||
|
||||
holder_ptr hldr;
|
||||
public:
|
||||
template<class value_t>
|
||||
any(value_t&& arg) : hldr(new holder_impl<typename std::decay<value_t>::type>( std::forward<value_t>(arg))) {}
|
||||
|
||||
any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {}
|
||||
//simple hack in order not to write enable_if<not any> for the template constructor
|
||||
any(any & src) : any (const_cast<any const&>(src)) {}
|
||||
|
||||
any() = default;
|
||||
any(any&& ) = default;
|
||||
|
||||
any& operator=(any&&) = default;
|
||||
|
||||
any& operator=(any const& src)
|
||||
{
|
||||
any copy(src);
|
||||
swap(*this, copy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class value_t>
|
||||
friend value_t* any_cast(any* operand);
|
||||
|
||||
template<class value_t>
|
||||
friend const value_t* any_cast(const any* operand);
|
||||
|
||||
template<class value_t>
|
||||
friend value_t& unsafe_any_cast(any& operand);
|
||||
|
||||
template<class value_t>
|
||||
friend const value_t& unsafe_any_cast(const any& operand);
|
||||
|
||||
friend void swap(any & lhs, any& rhs)
|
||||
{
|
||||
swap(lhs.hldr, rhs.hldr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class value_t>
|
||||
value_t* any_cast(any* operand)
|
||||
{
|
||||
auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
|
||||
if (casted){
|
||||
return & (casted->v);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<class value_t>
|
||||
const value_t* any_cast(const any* operand)
|
||||
{
|
||||
auto casted = internal::down_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand->hldr.get());
|
||||
if (casted){
|
||||
return & (casted->v);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<class value_t>
|
||||
value_t& any_cast(any& operand)
|
||||
{
|
||||
auto ptr = any_cast<value_t>(&operand);
|
||||
if (ptr)
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
throw_error(bad_any_cast());
|
||||
}
|
||||
|
||||
|
||||
template<class value_t>
|
||||
const value_t& any_cast(const any& operand)
|
||||
{
|
||||
auto ptr = any_cast<value_t>(&operand);
|
||||
if (ptr)
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
throw_error(bad_any_cast());
|
||||
}
|
||||
|
||||
template<class value_t>
|
||||
inline value_t& unsafe_any_cast(any& operand)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
return any_cast<value_t>(operand);
|
||||
#else
|
||||
return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class value_t>
|
||||
inline const value_t& unsafe_any_cast(const any& operand)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
return any_cast<value_t>(operand);
|
||||
#else
|
||||
return static_cast<any::holder_impl<typename std::decay<value_t>::type> *>(operand.hldr.get())->v;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Enable "multiple copy constructors specified" back
|
||||
# pragma warning(default: 4521)
|
||||
#endif
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_ANY_HPP
|
||||
19
3rdparty/opencv/inc/opencv2/gapi/util/compiler_hints.hpp
vendored
Normal file
19
3rdparty/opencv/inc/opencv2/gapi/util/compiler_hints.hpp
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// 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_UTIL_COMPILER_HINTS_HPP
|
||||
#define OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
//! Utility template function to prevent "unused" warnings by various compilers.
|
||||
template<typename T> void suppress_unused_warning( const T& ) {}
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#endif /* OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP */
|
||||
34
3rdparty/opencv/inc/opencv2/gapi/util/copy_through_move.hpp
vendored
Normal file
34
3rdparty/opencv/inc/opencv2/gapi/util/copy_through_move.hpp
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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) 2020 Intel Corporation
|
||||
|
||||
#ifndef OPENCV_GAPI_UTIL_COPY_THROUGH_MOVE_HPP
|
||||
#define OPENCV_GAPI_UTIL_COPY_THROUGH_MOVE_HPP
|
||||
|
||||
#include <opencv2/gapi/util/type_traits.hpp> //decay_t
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
//This is a tool to move initialize captures of a lambda in C++11
|
||||
template<typename T>
|
||||
struct copy_through_move_t{
|
||||
T value;
|
||||
const T& get() const {return value;}
|
||||
T& get() {return value;}
|
||||
copy_through_move_t(T&& g) : value(std::move(g)) {}
|
||||
copy_through_move_t(copy_through_move_t&&) = default;
|
||||
copy_through_move_t(copy_through_move_t const& lhs) : copy_through_move_t(std::move(const_cast<copy_through_move_t&>(lhs))) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
copy_through_move_t<util::decay_t<T>> copy_through_move(T&& t){
|
||||
return std::forward<T>(t);
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#endif /* OPENCV_GAPI_UTIL_COPY_THROUGH_MOVE_HPP */
|
||||
178
3rdparty/opencv/inc/opencv2/gapi/util/optional.hpp
vendored
Normal file
178
3rdparty/opencv/inc/opencv2/gapi/util/optional.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
// 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_UTIL_OPTIONAL_HPP
|
||||
#define OPENCV_GAPI_UTIL_OPTIONAL_HPP
|
||||
|
||||
#include <opencv2/gapi/util/variant.hpp>
|
||||
|
||||
// A poor man's `optional` implementation, incompletely modeled against C++17 spec.
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
class bad_optional_access: public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept override
|
||||
{
|
||||
return "Bad optional access";
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: nullopt_t
|
||||
|
||||
// Interface ///////////////////////////////////////////////////////////////
|
||||
template<typename T> class optional
|
||||
{
|
||||
public:
|
||||
// Constructors
|
||||
// NB.: there were issues with Clang 3.8 when =default() was used
|
||||
// instead {}
|
||||
optional() {}
|
||||
optional(const optional&) = default;
|
||||
explicit optional(T&&) noexcept;
|
||||
explicit optional(const T&) noexcept;
|
||||
optional(optional&&) noexcept;
|
||||
// TODO: optional(nullopt_t) noexcept;
|
||||
// TODO: optional(const optional<U> &)
|
||||
// TODO: optional(optional<U> &&)
|
||||
// TODO: optional(Args&&...)
|
||||
// TODO: optional(initializer_list<U>)
|
||||
// TODO: optional(U&& value);
|
||||
|
||||
// Assignment
|
||||
optional& operator=(const optional&) = default;
|
||||
optional& operator=(optional&&);
|
||||
|
||||
// Observers
|
||||
T* operator-> ();
|
||||
const T* operator-> () const;
|
||||
T& operator* ();
|
||||
const T& operator* () const;
|
||||
// TODO: && versions
|
||||
|
||||
operator bool() const noexcept;
|
||||
bool has_value() const noexcept;
|
||||
|
||||
T& value();
|
||||
const T& value() const;
|
||||
// TODO: && versions
|
||||
|
||||
template<class U>
|
||||
T value_or(U &&default_value) const;
|
||||
|
||||
void swap(optional &other) noexcept;
|
||||
void reset() noexcept;
|
||||
// TODO: emplace
|
||||
|
||||
// TODO: operator==, !=, <, <=, >, >=
|
||||
|
||||
private:
|
||||
struct nothing {};
|
||||
util::variant<nothing, T> m_holder;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
optional<typename std::decay<T>::type> make_optional(T&& value);
|
||||
|
||||
// TODO: Args... and initializer_list versions
|
||||
|
||||
// Implementation //////////////////////////////////////////////////////////
|
||||
template<class T> optional<T>::optional(T &&v) noexcept
|
||||
: m_holder(std::move(v))
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> optional<T>::optional(const T &v) noexcept
|
||||
: m_holder(v)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> optional<T>::optional(optional&& rhs) noexcept
|
||||
: m_holder(std::move(rhs.m_holder))
|
||||
{
|
||||
rhs.reset();
|
||||
}
|
||||
|
||||
template<class T> optional<T>& optional<T>::operator=(optional&& rhs)
|
||||
{
|
||||
m_holder = std::move(rhs.m_holder);
|
||||
rhs.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T> T* optional<T>::operator-> ()
|
||||
{
|
||||
return & *(*this);
|
||||
}
|
||||
|
||||
template<class T> const T* optional<T>::operator-> () const
|
||||
{
|
||||
return & *(*this);
|
||||
}
|
||||
|
||||
template<class T> T& optional<T>::operator* ()
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
template<class T> const T& optional<T>::operator* () const
|
||||
{
|
||||
return this->value();
|
||||
}
|
||||
|
||||
template<class T> optional<T>::operator bool() const noexcept
|
||||
{
|
||||
return this->has_value();
|
||||
}
|
||||
|
||||
template<class T> bool optional<T>::has_value() const noexcept
|
||||
{
|
||||
return util::holds_alternative<T>(m_holder);
|
||||
}
|
||||
|
||||
template<class T> T& optional<T>::value()
|
||||
{
|
||||
if (!this->has_value())
|
||||
throw_error(bad_optional_access());
|
||||
return util::get<T>(m_holder);
|
||||
}
|
||||
|
||||
template<class T> const T& optional<T>::value() const
|
||||
{
|
||||
if (!this->has_value())
|
||||
throw_error(bad_optional_access());
|
||||
return util::get<T>(m_holder);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class U> T optional<T>::value_or(U &&default_value) const
|
||||
{
|
||||
return (this->has_value() ? this->value() : T(default_value));
|
||||
}
|
||||
|
||||
template<class T> void optional<T>::swap(optional<T> &other) noexcept
|
||||
{
|
||||
m_holder.swap(other.m_holder);
|
||||
}
|
||||
|
||||
template<class T> void optional<T>::reset() noexcept
|
||||
{
|
||||
if (this->has_value())
|
||||
m_holder = nothing{};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
optional<typename std::decay<T>::type> make_optional(T&& value)
|
||||
{
|
||||
return optional<typename std::decay<T>::type>(std::forward<T>(value));
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_OPTIONAL_HPP
|
||||
36
3rdparty/opencv/inc/opencv2/gapi/util/throw.hpp
vendored
Normal file
36
3rdparty/opencv/inc/opencv2/gapi/util/throw.hpp
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// 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_UTIL_THROW_HPP
|
||||
#define OPENCV_GAPI_UTIL_THROW_HPP
|
||||
|
||||
#include <utility> // std::forward
|
||||
|
||||
#if !defined(__EXCEPTIONS)
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
template <class ExceptionType>
|
||||
[[noreturn]] void throw_error(ExceptionType &&e)
|
||||
{
|
||||
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
|
||||
throw std::forward<ExceptionType>(e);
|
||||
#else
|
||||
fprintf(stderr, "An exception thrown! %s\n" , e.what());
|
||||
fflush(stderr);
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_THROW_HPP
|
||||
31
3rdparty/opencv/inc/opencv2/gapi/util/type_traits.hpp
vendored
Normal file
31
3rdparty/opencv/inc/opencv2/gapi/util/type_traits.hpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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) 2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_UTIL_TYPE_TRAITS_HPP
|
||||
#define OPENCV_GAPI_UTIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
//these are C++14 parts of type_traits :
|
||||
template< bool B, class T = void >
|
||||
using enable_if_t = typename std::enable_if<B,T>::type;
|
||||
|
||||
template<typename T>
|
||||
using decay_t = typename std::decay<T>::type;
|
||||
|
||||
//this is not part of C++14 but still, of pretty common usage
|
||||
template<class T, class U, class V = void>
|
||||
using are_different_t = enable_if_t< !std::is_same<decay_t<T>, decay_t<U>>::value, V>;
|
||||
|
||||
} // namespace cv
|
||||
} // namespace util
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_TYPE_TRAITS_HPP
|
||||
190
3rdparty/opencv/inc/opencv2/gapi/util/util.hpp
vendored
Normal file
190
3rdparty/opencv/inc/opencv2/gapi/util/util.hpp
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
// 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-2019 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_UTIL_HPP
|
||||
#define OPENCV_GAPI_UTIL_HPP
|
||||
|
||||
#include <tuple>
|
||||
|
||||
// \cond HIDDEN_SYMBOLS
|
||||
// This header file contains some generic utility functions which are
|
||||
// used in other G-API Public API headers.
|
||||
//
|
||||
// PLEASE don't put any stuff here if it is NOT used in public API headers!
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Recursive integer sequence type, useful for enumerating elements of
|
||||
// template parameter packs.
|
||||
template<int... I> struct Seq { using next = Seq<I..., sizeof...(I)>; };
|
||||
template<int Sz> struct MkSeq { using type = typename MkSeq<Sz-1>::type::next; };
|
||||
template<> struct MkSeq<0>{ using type = Seq<>; };
|
||||
|
||||
// Checks if elements of variadic template satisfy the given Predicate.
|
||||
// Implemented via tuple, with an interface to accept plain type lists
|
||||
template<template<class> class, typename, typename...> struct all_satisfy;
|
||||
|
||||
template<template<class> class F, typename T, typename... Ts>
|
||||
struct all_satisfy<F, std::tuple<T, Ts...> >
|
||||
{
|
||||
static const constexpr bool value = F<T>::value
|
||||
&& all_satisfy<F, std::tuple<Ts...> >::value;
|
||||
};
|
||||
template<template<class> class F, typename T>
|
||||
struct all_satisfy<F, std::tuple<T> >
|
||||
{
|
||||
static const constexpr bool value = F<T>::value;
|
||||
};
|
||||
|
||||
template<template<class> class F, typename T, typename... Ts>
|
||||
struct all_satisfy: public all_satisfy<F, std::tuple<T, Ts...> > {};
|
||||
|
||||
// Permute given tuple type C with given integer sequence II
|
||||
// Sequence may be less than tuple C size.
|
||||
template<class, class> struct permute_tuple;
|
||||
|
||||
template<class C, int... IIs>
|
||||
struct permute_tuple<C, Seq<IIs...> >
|
||||
{
|
||||
using type = std::tuple< typename std::tuple_element<IIs, C>::type... >;
|
||||
};
|
||||
|
||||
// Given T..., generates a type sequence of sizeof...(T)-1 elements
|
||||
// which is T... without its last element
|
||||
// Implemented via tuple, with an interface to accept plain type lists
|
||||
template<typename T, typename... Ts> struct all_but_last;
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
struct all_but_last<std::tuple<T, Ts...> >
|
||||
{
|
||||
using C = std::tuple<T, Ts...>;
|
||||
using S = typename MkSeq<std::tuple_size<C>::value - 1>::type;
|
||||
using type = typename permute_tuple<C, S>::type;
|
||||
};
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
struct all_but_last: public all_but_last<std::tuple<T, Ts...> > {};
|
||||
|
||||
template<typename... Ts>
|
||||
using all_but_last_t = typename all_but_last<Ts...>::type;
|
||||
|
||||
// NB.: This is here because there's no constexpr std::max in C++11
|
||||
template<std::size_t S0, std::size_t... SS> struct max_of_t
|
||||
{
|
||||
static constexpr const std::size_t rest = max_of_t<SS...>::value;
|
||||
static constexpr const std::size_t value = rest > S0 ? rest : S0;
|
||||
};
|
||||
template<std::size_t S> struct max_of_t<S>
|
||||
{
|
||||
static constexpr const std::size_t value = S;
|
||||
};
|
||||
|
||||
template <typename...>
|
||||
struct contains : std::false_type{};
|
||||
|
||||
template <typename T1, typename T2, typename... Ts>
|
||||
struct contains<T1, T2, Ts...> : std::integral_constant<bool, std::is_same<T1, T2>::value ||
|
||||
contains<T1, Ts...>::value> {};
|
||||
template<typename T, typename... Types>
|
||||
struct contains<T, std::tuple<Types...>> : std::integral_constant<bool, contains<T, Types...>::value> {};
|
||||
|
||||
template <typename...>
|
||||
struct all_unique : std::true_type{};
|
||||
|
||||
template <typename T1, typename... Ts>
|
||||
struct all_unique<T1, Ts...> : std::integral_constant<bool, !contains<T1, Ts...>::value &&
|
||||
all_unique<Ts...>::value> {};
|
||||
|
||||
template<typename>
|
||||
struct tuple_wrap_helper;
|
||||
|
||||
template<typename T> struct tuple_wrap_helper
|
||||
{
|
||||
using type = std::tuple<T>;
|
||||
static type get(T&& obj) { return std::make_tuple(std::move(obj)); }
|
||||
};
|
||||
|
||||
template<typename... Objs>
|
||||
struct tuple_wrap_helper<std::tuple<Objs...>>
|
||||
{
|
||||
using type = std::tuple<Objs...>;
|
||||
static type get(std::tuple<Objs...>&& objs) { return std::forward<std::tuple<Objs...>>(objs); }
|
||||
};
|
||||
|
||||
template<typename... Ts>
|
||||
struct make_void { typedef void type;};
|
||||
|
||||
template<typename... Ts>
|
||||
using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace util
|
||||
{
|
||||
template<typename ...L>
|
||||
struct overload_lamba_set;
|
||||
|
||||
template<typename L1>
|
||||
struct overload_lamba_set<L1> : public L1
|
||||
{
|
||||
overload_lamba_set(L1&& lambda) : L1(std::move(lambda)) {}
|
||||
overload_lamba_set(const L1& lambda) : L1(lambda) {}
|
||||
|
||||
using L1::operator();
|
||||
};
|
||||
|
||||
template<typename L1, typename ...L>
|
||||
struct overload_lamba_set<L1, L...> : public L1, public overload_lamba_set<L...>
|
||||
{
|
||||
using base_type = overload_lamba_set<L...>;
|
||||
overload_lamba_set(L1 &&lambda1, L&& ...lambdas):
|
||||
L1(std::move(lambda1)),
|
||||
base_type(std::forward<L>(lambdas)...) {}
|
||||
|
||||
overload_lamba_set(const L1 &lambda1, L&& ...lambdas):
|
||||
L1(lambda1),
|
||||
base_type(std::forward<L>(lambdas)...) {}
|
||||
|
||||
using L1::operator();
|
||||
using base_type::operator();
|
||||
};
|
||||
|
||||
template<typename... L>
|
||||
overload_lamba_set<L...> overload_lambdas(L&& ...lambdas)
|
||||
{
|
||||
return overload_lamba_set<L...>(std::forward<L>(lambdas)...);
|
||||
}
|
||||
|
||||
template<typename ...T>
|
||||
struct find_adapter_impl;
|
||||
|
||||
template<typename AdapterT, typename T>
|
||||
struct find_adapter_impl<AdapterT, T>
|
||||
{
|
||||
using type = typename std::conditional<std::is_base_of<AdapterT, T>::value,
|
||||
T,
|
||||
void>::type;
|
||||
static constexpr bool found = std::is_base_of<AdapterT, T>::value;
|
||||
};
|
||||
|
||||
template<typename AdapterT, typename T, typename... Types>
|
||||
struct find_adapter_impl<AdapterT, T, Types...>
|
||||
{
|
||||
using type = typename std::conditional<std::is_base_of<AdapterT, T>::value,
|
||||
T,
|
||||
typename find_adapter_impl<AdapterT, Types...>::type>::type;
|
||||
static constexpr bool found = std::is_base_of<AdapterT, T>::value ||
|
||||
find_adapter_impl<AdapterT, Types...>::found;
|
||||
};
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
// \endcond
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_HPP
|
||||
658
3rdparty/opencv/inc/opencv2/gapi/util/variant.hpp
vendored
Normal file
658
3rdparty/opencv/inc/opencv2/gapi/util/variant.hpp
vendored
Normal file
@@ -0,0 +1,658 @@
|
||||
// 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_UTIL_VARIANT_HPP
|
||||
#define OPENCV_GAPI_UTIL_VARIANT_HPP
|
||||
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
#include <opencv2/gapi/util/compiler_hints.hpp>
|
||||
#include <opencv2/gapi/util/throw.hpp>
|
||||
#include <opencv2/gapi/util/util.hpp> // max_of_t
|
||||
#include <opencv2/gapi/util/type_traits.hpp>
|
||||
|
||||
// A poor man's `variant` implementation, incompletely modeled against C++17 spec.
|
||||
namespace cv
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<std::size_t I, typename Target, typename First, typename... Remaining>
|
||||
struct type_list_index_helper
|
||||
{
|
||||
static const constexpr bool is_same = std::is_same<Target, First>::value;
|
||||
static const constexpr std::size_t value =
|
||||
std::conditional<is_same, std::integral_constant<std::size_t, I>, type_list_index_helper<I + 1, Target, Remaining...>>::type::value;
|
||||
};
|
||||
|
||||
template<std::size_t I, typename Target, typename First>
|
||||
struct type_list_index_helper<I, Target, First>
|
||||
{
|
||||
static_assert(std::is_same<Target, First>::value, "Type not found");
|
||||
static const constexpr std::size_t value = I;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Target, typename... Types>
|
||||
struct type_list_index
|
||||
{
|
||||
static const constexpr std::size_t value = detail::type_list_index_helper<0, Target, Types...>::value;
|
||||
};
|
||||
|
||||
template<std::size_t Index, class... Types >
|
||||
struct type_list_element
|
||||
{
|
||||
using type = typename std::tuple_element<Index, std::tuple<Types...> >::type;
|
||||
};
|
||||
|
||||
class bad_variant_access: public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept override
|
||||
{
|
||||
return "Bad variant access";
|
||||
}
|
||||
};
|
||||
|
||||
// Interface ///////////////////////////////////////////////////////////////
|
||||
struct monostate {};
|
||||
inline bool operator==(const util::monostate&, const util::monostate&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename... Ts> // FIXME: no references, arrays, and void
|
||||
class variant
|
||||
{
|
||||
// FIXME: Replace with std::aligned_union after gcc4.8 support is dropped
|
||||
static constexpr const std::size_t S = cv::detail::max_of_t<sizeof(Ts)...>::value;
|
||||
static constexpr const std::size_t A = cv::detail::max_of_t<alignof(Ts)...>::value;
|
||||
using Memory = typename std::aligned_storage<S, A>::type[1];
|
||||
|
||||
template<typename T> struct cctr_h {
|
||||
static void help(Memory memory, const Memory from) {
|
||||
new (memory) T(*reinterpret_cast<const T*>(from));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct mctr_h {
|
||||
static void help(Memory memory, void *pval) {
|
||||
new (memory) T(std::move(*reinterpret_cast<T*>(pval)));
|
||||
}
|
||||
};
|
||||
|
||||
//FIXME: unify with cctr_h and mctr_h
|
||||
template<typename T> struct cnvrt_ctor_h {
|
||||
static void help(Memory memory, void* from) {
|
||||
using util::decay_t;
|
||||
new (memory) decay_t<T>(std::forward<T>(*reinterpret_cast<decay_t<T>*>(from)));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct copy_h {
|
||||
static void help(Memory to, const Memory from) {
|
||||
*reinterpret_cast<T*>(to) = *reinterpret_cast<const T*>(from);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct move_h {
|
||||
static void help(Memory to, Memory from) {
|
||||
*reinterpret_cast<T*>(to) = std::move(*reinterpret_cast<T*>(from));
|
||||
}
|
||||
};
|
||||
|
||||
//FIXME: unify with copy_h and move_h
|
||||
template<typename T> struct cnvrt_assign_h {
|
||||
static void help(Memory to, void* from) {
|
||||
using util::decay_t;
|
||||
*reinterpret_cast<decay_t<T>*>(to) = std::forward<T>(*reinterpret_cast<decay_t<T>*>(from));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct swap_h {
|
||||
static void help(Memory to, Memory from) {
|
||||
std::swap(*reinterpret_cast<T*>(to), *reinterpret_cast<T*>(from));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct dtor_h {
|
||||
static void help(Memory memory) {
|
||||
(void) memory; // MSCV warning
|
||||
reinterpret_cast<T*>(memory)->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct equal_h {
|
||||
static bool help(const Memory lhs, const Memory rhs) {
|
||||
const T& t_lhs = *reinterpret_cast<const T*>(lhs);
|
||||
const T& t_rhs = *reinterpret_cast<const T*>(rhs);
|
||||
return t_lhs == t_rhs;
|
||||
}
|
||||
};
|
||||
|
||||
typedef void (*CCtr) (Memory, const Memory); // Copy c-tor (variant)
|
||||
typedef void (*MCtr) (Memory, void*); // Generic move c-tor
|
||||
typedef void (*Copy) (Memory, const Memory); // Copy assignment
|
||||
typedef void (*Move) (Memory, Memory); // Move assignment
|
||||
|
||||
typedef void (*Swap) (Memory, Memory); // Swap
|
||||
typedef void (*Dtor) (Memory); // Destructor
|
||||
|
||||
using cnvrt_assgn_t = void (*) (Memory, void*); // Converting assignment (via std::forward)
|
||||
using cnvrt_ctor_t = void (*) (Memory, void*); // Converting constructor (via std::forward)
|
||||
|
||||
typedef bool (*Equal)(const Memory, const Memory); // Equality test (external)
|
||||
|
||||
static constexpr std::array<CCtr, sizeof...(Ts)> cctrs(){ return {{(&cctr_h<Ts>::help)...}};}
|
||||
static constexpr std::array<MCtr, sizeof...(Ts)> mctrs(){ return {{(&mctr_h<Ts>::help)...}};}
|
||||
static constexpr std::array<Copy, sizeof...(Ts)> cpyrs(){ return {{(©_h<Ts>::help)...}};}
|
||||
static constexpr std::array<Move, sizeof...(Ts)> mvers(){ return {{(&move_h<Ts>::help)...}};}
|
||||
static constexpr std::array<Swap, sizeof...(Ts)> swprs(){ return {{(&swap_h<Ts>::help)...}};}
|
||||
static constexpr std::array<Dtor, sizeof...(Ts)> dtors(){ return {{(&dtor_h<Ts>::help)...}};}
|
||||
|
||||
template<bool cond, typename T>
|
||||
struct conditional_ref : std::conditional<cond, typename std::remove_reference<T>::type&, typename std::remove_reference<T>::type > {};
|
||||
|
||||
template<bool cond, typename T>
|
||||
using conditional_ref_t = typename conditional_ref<cond, T>::type;
|
||||
|
||||
|
||||
template<bool is_lvalue_arg>
|
||||
static constexpr std::array<cnvrt_assgn_t, sizeof...(Ts)> cnvrt_assgnrs(){
|
||||
return {{(&cnvrt_assign_h<conditional_ref_t<is_lvalue_arg,Ts>>::help)...}};
|
||||
}
|
||||
|
||||
template<bool is_lvalue_arg>
|
||||
static constexpr std::array<cnvrt_ctor_t, sizeof...(Ts)> cnvrt_ctors(){
|
||||
return {{(&cnvrt_ctor_h<conditional_ref_t<is_lvalue_arg,Ts>>::help)...}};
|
||||
}
|
||||
|
||||
std::size_t m_index = 0;
|
||||
|
||||
protected:
|
||||
template<typename T, typename... Us> friend T& get(variant<Us...> &v);
|
||||
template<typename T, typename... Us> friend const T& get(const variant<Us...> &v);
|
||||
template<typename T, typename... Us> friend T* get_if(variant<Us...> *v) noexcept;
|
||||
template<typename T, typename... Us> friend const T* get_if(const variant<Us...> *v) noexcept;
|
||||
|
||||
template<typename... Us> friend bool operator==(const variant<Us...> &lhs,
|
||||
const variant<Us...> &rhs);
|
||||
Memory memory;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
variant() noexcept;
|
||||
variant(const variant& other);
|
||||
variant(variant&& other) noexcept;
|
||||
// are_different_t is a SFINAE trick to avoid variant(T &&t) with T=variant
|
||||
// for some reason, this version is called instead of variant(variant&& o) when
|
||||
// variant is used in STL containers (examples: vector assignment).
|
||||
template<
|
||||
typename T,
|
||||
typename = util::are_different_t<variant, T>
|
||||
>
|
||||
explicit variant(T&& t);
|
||||
// template<class T, class... Args> explicit variant(Args&&... args);
|
||||
// FIXME: other constructors
|
||||
|
||||
// Destructor
|
||||
~variant();
|
||||
|
||||
// Assignment
|
||||
variant& operator=(const variant& rhs);
|
||||
variant& operator=(variant &&rhs) noexcept;
|
||||
|
||||
// SFINAE trick to avoid operator=(T&&) with T=variant<>, see comment above
|
||||
template<
|
||||
typename T,
|
||||
typename = util::are_different_t<variant, T>
|
||||
>
|
||||
variant& operator=(T&& t) noexcept;
|
||||
|
||||
// Observers
|
||||
std::size_t index() const noexcept;
|
||||
// FIXME: valueless_by_exception()
|
||||
|
||||
// Modifiers
|
||||
// FIXME: emplace()
|
||||
void swap(variant &rhs) noexcept;
|
||||
|
||||
// Non-C++17x!
|
||||
template<typename T> static constexpr std::size_t index_of();
|
||||
};
|
||||
|
||||
// FIMXE: visit
|
||||
template<typename T, typename... Types>
|
||||
T* get_if(util::variant<Types...>* v) noexcept;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T* get_if(const util::variant<Types...>* v) noexcept;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
T& get(util::variant<Types...> &v);
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T& get(const util::variant<Types...> &v);
|
||||
|
||||
template<std::size_t Index, typename... Types>
|
||||
typename util::type_list_element<Index, Types...>::type& get(util::variant<Types...> &v);
|
||||
|
||||
template<std::size_t Index, typename... Types>
|
||||
const typename util::type_list_element<Index, Types...>::type& get(const util::variant<Types...> &v);
|
||||
|
||||
template<typename T, typename... Types>
|
||||
bool holds_alternative(const util::variant<Types...> &v) noexcept;
|
||||
|
||||
|
||||
// Visitor
|
||||
namespace detail
|
||||
{
|
||||
struct visitor_interface {};
|
||||
|
||||
// Class `visitor_return_type_deduction_helper`
|
||||
// introduces solution for deduction `return_type` in `visit` function in common way
|
||||
// for both Lambda and class Visitor and keep one interface invocation point: `visit` only
|
||||
// his helper class is required to unify return_type deduction mechanism because
|
||||
// for Lambda it is possible to take type of `decltype(visitor(get<0>(var)))`
|
||||
// but for class Visitor there is no operator() in base case,
|
||||
// because it provides `operator() (std::size_t index, ...)`
|
||||
// So `visitor_return_type_deduction_helper` expose `operator()`
|
||||
// uses only for class Visitor only for deduction `return type` in visit()
|
||||
template<typename R>
|
||||
struct visitor_return_type_deduction_helper
|
||||
{
|
||||
using return_type = R;
|
||||
|
||||
// to be used in Lambda return type deduction context only
|
||||
template<typename T>
|
||||
return_type operator() (T&&);
|
||||
};
|
||||
}
|
||||
|
||||
// Special purpose `static_visitor` can receive additional arguments
|
||||
template<typename R, typename Impl>
|
||||
struct static_visitor : public detail::visitor_interface,
|
||||
public detail::visitor_return_type_deduction_helper<R> {
|
||||
|
||||
// assign responsibility for return type deduction to helper class
|
||||
using return_type = typename detail::visitor_return_type_deduction_helper<R>::return_type;
|
||||
using detail::visitor_return_type_deduction_helper<R>::operator();
|
||||
friend Impl;
|
||||
|
||||
template<typename VariantValue, typename ...Args>
|
||||
return_type operator() (std::size_t index, VariantValue&& value, Args&& ...args)
|
||||
{
|
||||
suppress_unused_warning(index);
|
||||
return static_cast<Impl*>(this)-> visit(
|
||||
std::forward<VariantValue>(value),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
// Special purpose `static_indexed_visitor` can receive additional arguments
|
||||
// And make forwarding current variant index as runtime function argument to its `Impl`
|
||||
template<typename R, typename Impl>
|
||||
struct static_indexed_visitor : public detail::visitor_interface,
|
||||
public detail::visitor_return_type_deduction_helper<R> {
|
||||
|
||||
// assign responsibility for return type deduction to helper class
|
||||
using return_type = typename detail::visitor_return_type_deduction_helper<R>::return_type;
|
||||
using detail::visitor_return_type_deduction_helper<R>::operator();
|
||||
friend Impl;
|
||||
|
||||
template<typename VariantValue, typename ...Args>
|
||||
return_type operator() (std::size_t Index, VariantValue&& value, Args&& ...args)
|
||||
{
|
||||
return static_cast<Impl*>(this)-> visit(Index,
|
||||
std::forward<VariantValue>(value),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct variant_size;
|
||||
|
||||
template <class... Types>
|
||||
struct variant_size<util::variant<Types...>>
|
||||
: std::integral_constant<std::size_t, sizeof...(Types)> { };
|
||||
// FIXME: T&&, const TT&& versions.
|
||||
|
||||
// Implementation //////////////////////////////////////////////////////////
|
||||
template<typename... Ts>
|
||||
variant<Ts...>::variant() noexcept
|
||||
{
|
||||
typedef typename std::tuple_element<0, std::tuple<Ts...> >::type TFirst;
|
||||
new (memory) TFirst();
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
variant<Ts...>::variant(const variant &other)
|
||||
: m_index(other.m_index)
|
||||
{
|
||||
(cctrs()[m_index])(memory, other.memory);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
variant<Ts...>::variant(variant &&other) noexcept
|
||||
: m_index(other.m_index)
|
||||
{
|
||||
(mctrs()[m_index])(memory, other.memory);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<class T, typename>
|
||||
variant<Ts...>::variant(T&& t)
|
||||
: m_index(util::type_list_index<util::decay_t<T>, Ts...>::value)
|
||||
{
|
||||
const constexpr bool is_lvalue_arg = std::is_lvalue_reference<T>::value;
|
||||
(cnvrt_ctors<is_lvalue_arg>()[m_index])(memory, const_cast<util::decay_t<T> *>(&t));
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
variant<Ts...>::~variant()
|
||||
{
|
||||
(dtors()[m_index])(memory);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
variant<Ts...>& variant<Ts...>::operator=(const variant<Ts...> &rhs)
|
||||
{
|
||||
if (m_index != rhs.m_index)
|
||||
{
|
||||
(dtors()[ m_index])(memory);
|
||||
(cctrs()[rhs.m_index])(memory, rhs.memory);
|
||||
m_index = rhs.m_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
(cpyrs()[rhs.m_index])(memory, rhs.memory);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
variant<Ts...>& variant<Ts...>::operator=(variant<Ts...> &&rhs) noexcept
|
||||
{
|
||||
if (m_index != rhs.m_index)
|
||||
{
|
||||
(dtors()[ m_index])(memory);
|
||||
(mctrs()[rhs.m_index])(memory, rhs.memory);
|
||||
m_index = rhs.m_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
(mvers()[rhs.m_index])(memory, rhs.memory);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<typename T, typename>
|
||||
variant<Ts...>& variant<Ts...>::operator=(T&& t) noexcept
|
||||
{
|
||||
using decayed_t = util::decay_t<T>;
|
||||
// FIXME: No version with implicit type conversion available!
|
||||
const constexpr std::size_t t_index =
|
||||
util::type_list_index<decayed_t, Ts...>::value;
|
||||
|
||||
const constexpr bool is_lvalue_arg = std::is_lvalue_reference<T>::value;
|
||||
|
||||
if (t_index != m_index)
|
||||
{
|
||||
(dtors()[m_index])(memory);
|
||||
(cnvrt_ctors<is_lvalue_arg>()[t_index])(memory, &t);
|
||||
m_index = t_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
(cnvrt_assgnrs<is_lvalue_arg>()[m_index])(memory, &t);
|
||||
}
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
std::size_t util::variant<Ts...>::index() const noexcept
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
void variant<Ts...>::swap(variant<Ts...> &rhs) noexcept
|
||||
{
|
||||
if (m_index == rhs.index())
|
||||
{
|
||||
(swprs()[m_index](memory, rhs.memory));
|
||||
}
|
||||
else
|
||||
{
|
||||
variant<Ts...> tmp(std::move(*this));
|
||||
*this = std::move(rhs);
|
||||
rhs = std::move(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<typename T>
|
||||
constexpr std::size_t variant<Ts...>::index_of()
|
||||
{
|
||||
return util::type_list_index<T, Ts...>::value; // FIXME: tests!
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
T* get_if(util::variant<Types...>* v) noexcept
|
||||
{
|
||||
const constexpr std::size_t t_index =
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v && v->index() == t_index)
|
||||
return (T*)(&v->memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<T&>(v.memory);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T* get_if(const util::variant<Types...>* v) noexcept
|
||||
{
|
||||
const constexpr std::size_t t_index =
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v && v->index() == t_index)
|
||||
return (const T*)(&v->memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<const T&>(v.memory);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
T& get(util::variant<Types...> &v)
|
||||
{
|
||||
if (auto* p = get_if<T>(&v))
|
||||
return *p;
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T& get(const util::variant<Types...> &v)
|
||||
{
|
||||
if (auto* p = get_if<T>(&v))
|
||||
return *p;
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
|
||||
template<std::size_t Index, typename... Types>
|
||||
typename util::type_list_element<Index, Types...>::type& get(util::variant<Types...> &v)
|
||||
{
|
||||
using ReturnType = typename util::type_list_element<Index, Types...>::type;
|
||||
return const_cast<ReturnType&>(get<Index, Types...>(static_cast<const util::variant<Types...> &>(v)));
|
||||
}
|
||||
|
||||
template<std::size_t Index, typename... Types>
|
||||
const typename util::type_list_element<Index, Types...>::type& get(const util::variant<Types...> &v)
|
||||
{
|
||||
static_assert(Index < sizeof...(Types),
|
||||
"`Index` it out of bound of `util::variant` type list");
|
||||
using ReturnType = typename util::type_list_element<Index, Types...>::type;
|
||||
return get<ReturnType>(v);
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
bool holds_alternative(const util::variant<Types...> &v) noexcept
|
||||
{
|
||||
return v.index() == util::variant<Types...>::template index_of<T>();
|
||||
}
|
||||
|
||||
template<typename... Us> bool operator==(const variant<Us...> &lhs,
|
||||
const variant<Us...> &rhs)
|
||||
{
|
||||
using V = variant<Us...>;
|
||||
|
||||
// Instantiate table only here since it requires operator== for <Us...>
|
||||
// <Us...> should have operator== only if this one is used, not in general
|
||||
static const std::array<typename V::Equal, sizeof...(Us)> eqs = {
|
||||
{(&V::template equal_h<Us>::help)...}
|
||||
};
|
||||
if (lhs.index() != rhs.index())
|
||||
return false;
|
||||
return (eqs[lhs.index()])(lhs.memory, rhs.memory);
|
||||
}
|
||||
|
||||
template<typename... Us> bool operator!=(const variant<Us...> &lhs,
|
||||
const variant<Us...> &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// terminate recursion implementation for `non-void` ReturnType
|
||||
template<typename ReturnType, std::size_t CurIndex, std::size_t ElemCount,
|
||||
typename Visitor, typename Variant, typename... VisitorArgs>
|
||||
ReturnType apply_visitor_impl(Visitor&&, Variant&,
|
||||
std::true_type, std::false_type,
|
||||
VisitorArgs&& ...)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// terminate recursion implementation for `void` ReturnType
|
||||
template<typename ReturnType, std::size_t CurIndex, std::size_t ElemCount,
|
||||
typename Visitor, typename Variant, typename... VisitorArgs>
|
||||
void apply_visitor_impl(Visitor&&, Variant&,
|
||||
std::true_type, std::true_type,
|
||||
VisitorArgs&& ...)
|
||||
{
|
||||
}
|
||||
|
||||
// Intermediate resursion processor for Lambda Visitors
|
||||
template<typename ReturnType, std::size_t CurIndex, std::size_t ElemCount,
|
||||
typename Visitor, typename Variant, bool no_return_value, typename... VisitorArgs>
|
||||
typename std::enable_if<!std::is_base_of<visitor_interface, typename std::decay<Visitor>::type>::value, ReturnType>::type
|
||||
apply_visitor_impl(Visitor&& visitor, Variant&& v, std::false_type not_processed,
|
||||
std::integral_constant<bool, no_return_value> should_no_return,
|
||||
VisitorArgs&& ...args)
|
||||
{
|
||||
static_assert(std::is_same<ReturnType, decltype(visitor(get<CurIndex>(v)))>::value,
|
||||
"Different `ReturnType`s detected! All `Visitor::visit` or `overload_lamba_set`"
|
||||
" must return the same type");
|
||||
suppress_unused_warning(not_processed);
|
||||
if (v.index() == CurIndex)
|
||||
{
|
||||
return visitor.operator()(get<CurIndex>(v), std::forward<VisitorArgs>(args)... );
|
||||
}
|
||||
|
||||
using is_variant_processed_t = std::integral_constant<bool, CurIndex + 1 >= ElemCount>;
|
||||
return apply_visitor_impl<ReturnType, CurIndex +1, ElemCount>(
|
||||
std::forward<Visitor>(visitor),
|
||||
std::forward<Variant>(v),
|
||||
is_variant_processed_t{},
|
||||
should_no_return,
|
||||
std::forward<VisitorArgs>(args)...);
|
||||
}
|
||||
|
||||
//Visual Studio 2014 compilation fix: cast visitor to base class before invoke operator()
|
||||
template<std::size_t CurIndex, typename ReturnType, typename Visitor, class Value, typename... VisitorArgs>
|
||||
typename std::enable_if<std::is_base_of<static_visitor<ReturnType, typename std::decay<Visitor>::type>,
|
||||
typename std::decay<Visitor>::type>::value, ReturnType>::type
|
||||
invoke_class_visitor(Visitor& visitor, Value&& v, VisitorArgs&&...args)
|
||||
{
|
||||
return static_cast<static_visitor<ReturnType, typename std::decay<Visitor>::type>&>(visitor).operator() (CurIndex, std::forward<Value>(v), std::forward<VisitorArgs>(args)... );
|
||||
}
|
||||
|
||||
//Visual Studio 2014 compilation fix: cast visitor to base class before invoke operator()
|
||||
template<std::size_t CurIndex, typename ReturnType, typename Visitor, class Value, typename... VisitorArgs>
|
||||
typename std::enable_if<std::is_base_of<static_indexed_visitor<ReturnType, typename std::decay<Visitor>::type>,
|
||||
typename std::decay<Visitor>::type>::value, ReturnType>::type
|
||||
invoke_class_visitor(Visitor& visitor, Value&& v, VisitorArgs&&...args)
|
||||
{
|
||||
return static_cast<static_indexed_visitor<ReturnType, typename std::decay<Visitor>::type>&>(visitor).operator() (CurIndex, std::forward<Value>(v), std::forward<VisitorArgs>(args)... );
|
||||
}
|
||||
|
||||
// Intermediate recursion processor for special case `visitor_interface` derived Visitors
|
||||
template<typename ReturnType, std::size_t CurIndex, std::size_t ElemCount,
|
||||
typename Visitor, typename Variant, bool no_return_value, typename... VisitorArgs>
|
||||
typename std::enable_if<std::is_base_of<visitor_interface, typename std::decay<Visitor>::type>::value, ReturnType>::type
|
||||
apply_visitor_impl(Visitor&& visitor, Variant&& v, std::false_type not_processed,
|
||||
std::integral_constant<bool, no_return_value> should_no_return,
|
||||
VisitorArgs&& ...args)
|
||||
{
|
||||
static_assert(std::is_same<ReturnType, decltype(visitor(get<CurIndex>(v)))>::value,
|
||||
"Different `ReturnType`s detected! All `Visitor::visit` or `overload_lamba_set`"
|
||||
" must return the same type");
|
||||
suppress_unused_warning(not_processed);
|
||||
if (v.index() == CurIndex)
|
||||
{
|
||||
return invoke_class_visitor<CurIndex, ReturnType>(visitor, get<CurIndex>(v), std::forward<VisitorArgs>(args)... );
|
||||
}
|
||||
|
||||
using is_variant_processed_t = std::integral_constant<bool, CurIndex + 1 >= ElemCount>;
|
||||
return apply_visitor_impl<ReturnType, CurIndex +1, ElemCount>(
|
||||
std::forward<Visitor>(visitor),
|
||||
std::forward<Variant>(v),
|
||||
is_variant_processed_t{},
|
||||
should_no_return,
|
||||
std::forward<VisitorArgs>(args)...);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
template<typename Visitor, typename Variant, typename... VisitorArg>
|
||||
auto visit(Visitor &visitor, const Variant& var, VisitorArg &&...args) -> decltype(visitor(get<0>(var)))
|
||||
{
|
||||
constexpr std::size_t varsize = util::variant_size<Variant>::value;
|
||||
static_assert(varsize != 0, "utils::variant must contains one type at least ");
|
||||
using is_variant_processed_t = std::false_type;
|
||||
|
||||
using ReturnType = decltype(visitor(get<0>(var)));
|
||||
using return_t = std::is_same<ReturnType, void>;
|
||||
return detail::apply_visitor_impl<ReturnType, 0, varsize, Visitor>(
|
||||
std::forward<Visitor>(visitor),
|
||||
var, is_variant_processed_t{},
|
||||
return_t{},
|
||||
std::forward<VisitorArg>(args)...);
|
||||
}
|
||||
|
||||
template<typename Visitor, typename Variant>
|
||||
auto visit(Visitor&& visitor, const Variant& var) -> decltype(visitor(get<0>(var)))
|
||||
{
|
||||
constexpr std::size_t varsize = util::variant_size<Variant>::value;
|
||||
static_assert(varsize != 0, "utils::variant must contains one type at least ");
|
||||
using is_variant_processed_t = std::false_type;
|
||||
|
||||
using ReturnType = decltype(visitor(get<0>(var)));
|
||||
using return_t = std::is_same<ReturnType, void>;
|
||||
return detail::apply_visitor_impl<ReturnType, 0, varsize, Visitor>(
|
||||
std::forward<Visitor>(visitor),
|
||||
var, is_variant_processed_t{},
|
||||
return_t{});
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_VARIANT_HPP
|
||||
Reference in New Issue
Block a user