add part of opencv
This commit is contained in:
186
Lib/opencv/build/include/opencv2/gapi/util/any.hpp
Normal file
186
Lib/opencv/build/include/opencv2/gapi/util/any.hpp
Normal file
@@ -0,0 +1,186 @@
|
||||
// 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
|
||||
#warning used static cast instead of dynamic because RTTI is disabled
|
||||
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
|
||||
@@ -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 */
|
||||
178
Lib/opencv/build/include/opencv2/gapi/util/optional.hpp
Normal file
178
Lib/opencv/build/include/opencv2/gapi/util/optional.hpp
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 &&value) noexcept;
|
||||
explicit optional(const T &value) 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& rhs) = default;
|
||||
optional& operator=(optional&& rhs);
|
||||
|
||||
// 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(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
Lib/opencv/build/include/opencv2/gapi/util/throw.hpp
Normal file
36
Lib/opencv/build/include/opencv2/gapi/util/throw.hpp
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
|
||||
124
Lib/opencv/build/include/opencv2/gapi/util/util.hpp
Normal file
124
Lib/opencv/build/include/opencv2/gapi/util/util.hpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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); }
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
||||
// \endcond
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_HPP
|
||||
379
Lib/opencv/build/include/opencv2/gapi/util/variant.hpp
Normal file
379
Lib/opencv/build/include/opencv2/gapi/util/variant.hpp
Normal file
@@ -0,0 +1,379 @@
|
||||
// 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/throw.hpp>
|
||||
#include <opencv2/gapi/util/util.hpp> // max_of_t
|
||||
|
||||
// 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<class T, class U, class V> using are_different =
|
||||
std::enable_if<!std::is_same<typename std::decay<T>::type,
|
||||
typename std::decay<U>::type>::value,
|
||||
V>;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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 vctr_h {
|
||||
static void help(Memory memory, const void* pval) {
|
||||
new (memory) T(*reinterpret_cast<const T*>(pval));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct mctr_h {
|
||||
static void help(Memory memory, void *pval) {
|
||||
new (memory) T(std::move(*reinterpret_cast<T*>(pval)));
|
||||
}
|
||||
};
|
||||
|
||||
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, const Memory from) {
|
||||
*reinterpret_cast<T*>(to) = std::move(*reinterpret_cast<const 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 (*VCtr) (Memory, const void*); // Copy c-tor (value)
|
||||
typedef void (*MCtr) (Memory, void*); // Generic move c-tor
|
||||
typedef void (*Copy) (Memory, const Memory); // Copy assignment
|
||||
typedef void (*Move) (Memory, const Memory); // Move assignment
|
||||
typedef void (*Swap) (Memory, Memory); // Swap
|
||||
typedef void (*Dtor) (Memory); // Destructor
|
||||
|
||||
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<VCtr, sizeof...(Ts)> vctrs(){ return {{(&vctr_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)...}};}
|
||||
|
||||
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... 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;
|
||||
template<typename T> explicit variant(const T& t);
|
||||
// are_different 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> explicit variant(T&& t, typename detail::are_different<variant, T, int>::type = 0);
|
||||
// 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<class T>
|
||||
typename detail::are_different<variant, T, variant&>
|
||||
::type 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(util::variant<Types...> &v);
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T& get(const util::variant<Types...> &v);
|
||||
|
||||
template<typename T, typename... Types>
|
||||
bool holds_alternative(const util::variant<Types...> &v) noexcept;
|
||||
|
||||
// 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>
|
||||
variant<Ts...>::variant(const T& t)
|
||||
: m_index(util::type_list_index<T, Ts...>::value)
|
||||
{
|
||||
(vctrs()[m_index])(memory, &t);
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
template<class T>
|
||||
variant<Ts...>::variant(T&& t, typename detail::are_different<variant, T, int>::type)
|
||||
: m_index(util::type_list_index<typename std::remove_reference<T>::type, Ts...>::value)
|
||||
{
|
||||
(mctrs()[m_index])(memory, &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<class T> typename detail::are_different<variant<Ts...>, T, variant<Ts...>&>
|
||||
::type variant<Ts...>::operator=(T&& t) noexcept
|
||||
{
|
||||
// FIXME: No version with implicit type conversion available!
|
||||
static const constexpr std::size_t t_index =
|
||||
util::type_list_index<T, Ts...>::value;
|
||||
|
||||
if (t_index == m_index)
|
||||
{
|
||||
util::get<T>(*this) = std::move(t);
|
||||
return *this;
|
||||
}
|
||||
else return (*this = variant(std::move(t)));
|
||||
}
|
||||
|
||||
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(util::variant<Types...> &v)
|
||||
{
|
||||
const constexpr std::size_t t_index =
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v.index() == t_index)
|
||||
return *(T*)(&v.memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<T&>(v.memory);
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
|
||||
template<typename T, typename... Types>
|
||||
const T& get(const util::variant<Types...> &v)
|
||||
{
|
||||
const constexpr std::size_t t_index =
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v.index() == t_index)
|
||||
return *(const T*)(&v.memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<const T&>(v.memory);
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
|
||||
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 cv
|
||||
} // namespace util
|
||||
|
||||
#endif // OPENCV_GAPI_UTIL_VARIANT_HPP
|
||||
Reference in New Issue
Block a user