qtypeinfo.h: move QTypeTraits part to qttypetraits.h
Makes sense to collect the stuff in a similarly-named header, and it's not like any of the QTypeTraits stuff was needed for QTypeInfo. Makes #include <qtypeinfo.h> _much_ lighter again, at the expense of qminmax.h now getting <variant>, <tuple> and <optional> instead, but qminmax.h is much easier to avoid in Qt headers (just use the std versions) than qtypeinfo.h. [ChangeLog][QtCore][Potentially Source-Incompatible Changes] The qtypeinfo.h header no longer transitively includes <optional>, <tuple> and <variant>. Task-number: QTBUG-97601 Change-Id: Ied96113f38c1232fef3ec79847ee62f06c68f268 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit b2eb422699118f4ae8370519b4c7bb3fe121beb2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
ea588a8a2b
commit
aec1edfe40
@ -7,8 +7,11 @@
|
||||
#include <QtCore/qtconfigmacros.h>
|
||||
#include <QtCore/qtdeprecationmarkers.h>
|
||||
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#if 0
|
||||
#pragma qt_class(QtTypeTraits)
|
||||
@ -78,6 +81,192 @@ struct Promoted
|
||||
template <typename T, typename U>
|
||||
using Promoted = typename detail::Promoted<T, U>::type;
|
||||
|
||||
/*
|
||||
The templates below aim to find out whether one can safely instantiate an operator==() or
|
||||
operator<() for a type.
|
||||
|
||||
This is tricky for containers, as most containers have unconstrained comparison operators, even though they
|
||||
rely on the corresponding operators for its content.
|
||||
This is especially true for all of the STL template classes that have a comparison operator defined, and
|
||||
leads to the situation, that the compiler would try to instantiate the operator, and fail if any
|
||||
of its template arguments does not have the operator implemented.
|
||||
|
||||
The code tries to cover the relevant cases for Qt and the STL, by checking (recusrsively) the value_type
|
||||
of a container (if it exists), and checking the template arguments of pair, tuple and variant.
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
// find out whether T is a conteiner
|
||||
// this is required to check the value type of containers for the existence of the comparison operator
|
||||
template <typename, typename = void>
|
||||
struct is_container : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_container<T, std::void_t<
|
||||
typename T::value_type,
|
||||
std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>
|
||||
>> : std::true_type {};
|
||||
|
||||
|
||||
// Checks the existence of the comparison operator for the class itself
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_FLOAT_COMPARE
|
||||
template <typename, typename = void>
|
||||
struct has_operator_equal : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_operator_equal<T, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
QT_WARNING_POP
|
||||
|
||||
// Two forward declarations
|
||||
template<typename T, bool = is_container<T>::value>
|
||||
struct expand_operator_equal_container;
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple;
|
||||
|
||||
// the entry point for the public method
|
||||
template<typename T>
|
||||
using expand_operator_equal = expand_operator_equal_container<T>;
|
||||
|
||||
// if T isn't a container check if it's a tuple like object
|
||||
template<typename T, bool>
|
||||
struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
|
||||
// if T::value_type exists, check first T::value_type, then T itself
|
||||
template<typename T>
|
||||
struct expand_operator_equal_container<T, true> :
|
||||
std::conjunction<
|
||||
std::disjunction<
|
||||
std::is_same<T, typename T::value_type>, // avoid endless recursion
|
||||
expand_operator_equal<typename T::value_type>
|
||||
>, expand_operator_equal_tuple<T>> {};
|
||||
|
||||
// recursively check the template arguments of a tuple like object
|
||||
template<typename ...T>
|
||||
using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T>...>;
|
||||
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple : has_operator_equal<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
|
||||
template<typename T1, typename T2>
|
||||
struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_equal_tuple<std::tuple<T...>> : expand_operator_equal_recursive<T...> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_equal_tuple<std::variant<T...>> : expand_operator_equal_recursive<T...> {};
|
||||
|
||||
// the same for operator<(), see above for explanations
|
||||
template <typename, typename = void>
|
||||
struct has_operator_less_than : std::false_type{};
|
||||
template <typename T>
|
||||
struct has_operator_less_than<T, std::void_t<decltype(bool(std::declval<const T&>() < std::declval<const T&>()))>>
|
||||
: std::true_type{};
|
||||
|
||||
template<typename T, bool = is_container<T>::value>
|
||||
struct expand_operator_less_than_container;
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple;
|
||||
|
||||
template<typename T>
|
||||
using expand_operator_less_than = expand_operator_less_than_container<T>;
|
||||
|
||||
template<typename T, bool>
|
||||
struct expand_operator_less_than_container : expand_operator_less_than_tuple<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_container<T, true> :
|
||||
std::conjunction<
|
||||
std::disjunction<
|
||||
std::is_same<T, typename T::value_type>,
|
||||
expand_operator_less_than<typename T::value_type>
|
||||
>, expand_operator_less_than_tuple<T>
|
||||
> {};
|
||||
|
||||
template<typename ...T>
|
||||
using expand_operator_less_than_recursive = std::conjunction<expand_operator_less_than<T>...>;
|
||||
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
|
||||
template<typename T1, typename T2>
|
||||
struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_less_than_tuple<std::tuple<T...>> : expand_operator_less_than_recursive<T...> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_less_than_tuple<std::variant<T...>> : expand_operator_less_than_recursive<T...> {};
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_dereferenceable : std::false_type {};
|
||||
|
||||
template<typename T>
|
||||
struct is_dereferenceable<T, std::void_t<decltype(std::declval<T>().operator->())> >
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value;
|
||||
|
||||
template<typename T>
|
||||
struct has_operator_equal : detail::expand_operator_equal<T> {};
|
||||
template<typename T>
|
||||
inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value;
|
||||
|
||||
template <typename Container, typename T>
|
||||
using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>;
|
||||
|
||||
template<typename T>
|
||||
struct has_operator_less_than : detail::expand_operator_less_than<T> {};
|
||||
template<typename T>
|
||||
inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value;
|
||||
|
||||
template <typename Container, typename T>
|
||||
using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>;
|
||||
|
||||
template <typename ...T>
|
||||
using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>;
|
||||
|
||||
template <typename Container, typename ...T>
|
||||
using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>;
|
||||
|
||||
template <typename ...T>
|
||||
using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>;
|
||||
|
||||
template <typename Container, typename ...T>
|
||||
using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
const T &const_reference();
|
||||
template<typename T>
|
||||
T &reference();
|
||||
|
||||
}
|
||||
|
||||
template <typename Stream, typename, typename = void>
|
||||
struct has_ostream_operator : std::false_type {};
|
||||
template <typename Stream, typename T>
|
||||
struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>>
|
||||
: std::true_type {};
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
|
||||
|
||||
template <typename Stream, typename Container, typename T>
|
||||
using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>;
|
||||
|
||||
template <typename Stream, typename, typename = void>
|
||||
struct has_istream_operator : std::false_type {};
|
||||
template <typename Stream, typename T>
|
||||
struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>>
|
||||
: std::true_type {};
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
|
||||
template <typename Stream, typename Container, typename T>
|
||||
using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>;
|
||||
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
|
||||
|
||||
} // namespace QTypeTraits
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -8,9 +8,6 @@
|
||||
#include <QtCore/qcompilerdetection.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
|
||||
#include <variant>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -186,197 +183,5 @@ template<typename T> class QFlags;
|
||||
template<typename T>
|
||||
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
|
||||
|
||||
namespace QTypeTraits
|
||||
{
|
||||
|
||||
/*
|
||||
The templates below aim to find out whether one can safely instantiate an operator==() or
|
||||
operator<() for a type.
|
||||
|
||||
This is tricky for containers, as most containers have unconstrained comparison operators, even though they
|
||||
rely on the corresponding operators for its content.
|
||||
This is especially true for all of the STL template classes that have a comparison operator defined, and
|
||||
leads to the situation, that the compiler would try to instantiate the operator, and fail if any
|
||||
of its template arguments does not have the operator implemented.
|
||||
|
||||
The code tries to cover the relevant cases for Qt and the STL, by checking (recusrsively) the value_type
|
||||
of a container (if it exists), and checking the template arguments of pair, tuple and variant.
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
// find out whether T is a conteiner
|
||||
// this is required to check the value type of containers for the existence of the comparison operator
|
||||
template <typename, typename = void>
|
||||
struct is_container : std::false_type {};
|
||||
template <typename T>
|
||||
struct is_container<T, std::void_t<
|
||||
typename T::value_type,
|
||||
std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>
|
||||
>> : std::true_type {};
|
||||
|
||||
|
||||
// Checks the existence of the comparison operator for the class itself
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_FLOAT_COMPARE
|
||||
template <typename, typename = void>
|
||||
struct has_operator_equal : std::false_type {};
|
||||
template <typename T>
|
||||
struct has_operator_equal<T, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const T&>()))>>
|
||||
: std::true_type {};
|
||||
QT_WARNING_POP
|
||||
|
||||
// Two forward declarations
|
||||
template<typename T, bool = is_container<T>::value>
|
||||
struct expand_operator_equal_container;
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple;
|
||||
|
||||
// the entry point for the public method
|
||||
template<typename T>
|
||||
using expand_operator_equal = expand_operator_equal_container<T>;
|
||||
|
||||
// if T isn't a container check if it's a tuple like object
|
||||
template<typename T, bool>
|
||||
struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
|
||||
// if T::value_type exists, check first T::value_type, then T itself
|
||||
template<typename T>
|
||||
struct expand_operator_equal_container<T, true> :
|
||||
std::conjunction<
|
||||
std::disjunction<
|
||||
std::is_same<T, typename T::value_type>, // avoid endless recursion
|
||||
expand_operator_equal<typename T::value_type>
|
||||
>, expand_operator_equal_tuple<T>> {};
|
||||
|
||||
// recursively check the template arguments of a tuple like object
|
||||
template<typename ...T>
|
||||
using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T>...>;
|
||||
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple : has_operator_equal<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
|
||||
template<typename T1, typename T2>
|
||||
struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_equal_tuple<std::tuple<T...>> : expand_operator_equal_recursive<T...> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_equal_tuple<std::variant<T...>> : expand_operator_equal_recursive<T...> {};
|
||||
|
||||
// the same for operator<(), see above for explanations
|
||||
template <typename, typename = void>
|
||||
struct has_operator_less_than : std::false_type{};
|
||||
template <typename T>
|
||||
struct has_operator_less_than<T, std::void_t<decltype(bool(std::declval<const T&>() < std::declval<const T&>()))>>
|
||||
: std::true_type{};
|
||||
|
||||
template<typename T, bool = is_container<T>::value>
|
||||
struct expand_operator_less_than_container;
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple;
|
||||
|
||||
template<typename T>
|
||||
using expand_operator_less_than = expand_operator_less_than_container<T>;
|
||||
|
||||
template<typename T, bool>
|
||||
struct expand_operator_less_than_container : expand_operator_less_than_tuple<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_container<T, true> :
|
||||
std::conjunction<
|
||||
std::disjunction<
|
||||
std::is_same<T, typename T::value_type>,
|
||||
expand_operator_less_than<typename T::value_type>
|
||||
>, expand_operator_less_than_tuple<T>
|
||||
> {};
|
||||
|
||||
template<typename ...T>
|
||||
using expand_operator_less_than_recursive = std::conjunction<expand_operator_less_than<T>...>;
|
||||
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
|
||||
template<typename T>
|
||||
struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
|
||||
template<typename T1, typename T2>
|
||||
struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_less_than_tuple<std::tuple<T...>> : expand_operator_less_than_recursive<T...> {};
|
||||
template<typename ...T>
|
||||
struct expand_operator_less_than_tuple<std::variant<T...>> : expand_operator_less_than_recursive<T...> {};
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_dereferenceable : std::false_type {};
|
||||
|
||||
template<typename T>
|
||||
struct is_dereferenceable<T, std::void_t<decltype(std::declval<T>().operator->())> >
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value;
|
||||
|
||||
template<typename T>
|
||||
struct has_operator_equal : detail::expand_operator_equal<T> {};
|
||||
template<typename T>
|
||||
inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value;
|
||||
|
||||
template <typename Container, typename T>
|
||||
using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>;
|
||||
|
||||
template<typename T>
|
||||
struct has_operator_less_than : detail::expand_operator_less_than<T> {};
|
||||
template<typename T>
|
||||
inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value;
|
||||
|
||||
template <typename Container, typename T>
|
||||
using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>;
|
||||
|
||||
template <typename ...T>
|
||||
using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>;
|
||||
|
||||
template <typename Container, typename ...T>
|
||||
using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>;
|
||||
|
||||
template <typename ...T>
|
||||
using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>;
|
||||
|
||||
template <typename Container, typename ...T>
|
||||
using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
const T &const_reference();
|
||||
template<typename T>
|
||||
T &reference();
|
||||
|
||||
}
|
||||
|
||||
template <typename Stream, typename, typename = void>
|
||||
struct has_ostream_operator : std::false_type {};
|
||||
template <typename Stream, typename T>
|
||||
struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>>
|
||||
: std::true_type {};
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
|
||||
|
||||
template <typename Stream, typename Container, typename T>
|
||||
using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>;
|
||||
|
||||
template <typename Stream, typename, typename = void>
|
||||
struct has_istream_operator : std::false_type {};
|
||||
template <typename Stream, typename T>
|
||||
struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>>
|
||||
: std::true_type {};
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
|
||||
template <typename Stream, typename Container, typename T>
|
||||
using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>;
|
||||
|
||||
template <typename Stream, typename T>
|
||||
inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
#endif // QTYPEINFO_H
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
#include <QtCore/qtextstream.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
#include <QtCore/qtypes.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qcontiguouscache.h>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#endif
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <array>
|
||||
#include <new>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
#include <QtCore/qbindingstorage.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <QtCore/qtaggedpointer.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QtCore/qiodevicebase.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <iterator> // std::distance(), std::next()
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <QtCore/qassert.h>
|
||||
#include <QtCore/qtclasshelpermacros.h>
|
||||
#include <QtCore/qtcoreexports.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
#include <QtCore/qtypeinfo.h>
|
||||
|
||||
#include <climits>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <QtCore/qiterator.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qrefcount.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <functional> // for std::hash
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <QtCore/qiterator.h>
|
||||
#include <QtCore/qcontainertools_impl.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qshareddata_impl.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qcontainertools_impl.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <QtCore/qalgorithms.h>
|
||||
#include <QtCore/qcontainertools_impl.h>
|
||||
#include <QtCore/qhashfunctions.h>
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <initializer_list>
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <QtTest/qttestglobal.h>
|
||||
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
#if QT_CONFIG(itemmodel)
|
||||
# include <QtCore/qabstractitemmodel.h>
|
||||
#endif
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <qvariant.h>
|
||||
|
||||
#include <QtCore/qttypetraits.h>
|
||||
|
||||
// don't assume <type_traits>
|
||||
template <typename T, typename U>
|
||||
constexpr inline bool my_is_same_v = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user