diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2012-03-12 21:03:49 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@nokia.com> | 2012-03-12 21:03:49 +0100 |
commit | d5098f2802255da10b749b93705084ad1fdfc6a5 (patch) | |
tree | 6462008a4ab7d13435d93490fed96c62c516cbdf /src/corelib/global | |
parent | d5a85940f785459d7b982d5fdf59a9fd18825092 (diff) | |
parent | b5b41c18345719612e5411cc482466d2dbafdaf7 (diff) |
Merge remote-tracking branch 'origin/master' into api_changes
Conflicts:
tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
Change-Id: I884afc3b6d65c6411733a897a1949e19393573a7
Diffstat (limited to 'src/corelib/global')
-rw-r--r-- | src/corelib/global/global.pri | 4 | ||||
-rw-r--r-- | src/corelib/global/qisenum.h | 64 | ||||
-rw-r--r-- | src/corelib/global/qprocessordetection.h | 26 | ||||
-rw-r--r-- | src/corelib/global/qsysinfo.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qtypetraits.h | 420 |
5 files changed, 507 insertions, 9 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 49128374e0..58cff6b81c 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -11,7 +11,9 @@ HEADERS += \ global/qnumeric.h \ global/qlogging.h \ global/qtypeinfo.h \ - global/qsysinfo.h + global/qsysinfo.h \ + global/qisenum.h \ + global/qtypetraits.h SOURCES += \ global/qglobal.cpp \ diff --git a/src/corelib/global/qisenum.h b/src/corelib/global/qisenum.h new file mode 100644 index 0000000000..c9b6ec6695 --- /dev/null +++ b/src/corelib/global/qisenum.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qglobal.h> + +#ifndef QISENUM_H +#define QISENUM_H + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#ifndef Q_IS_ENUM +# if defined(Q_CC_GNU) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define Q_IS_ENUM(x) __is_enum(x) +# elif defined(Q_CC_MSVC) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER >=140050215) +# define Q_IS_ENUM(x) __is_enum(x) +# else +# include <QtCore/qtypetraits.h> +# define Q_IS_ENUM(x) QtPrivate::is_enum<x>::value +# endif +#endif + +QT_END_HEADER +QT_END_NAMESPACE + +#endif // QISENUM_H diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 1f16f090a9..d62794e706 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -75,7 +75,7 @@ /* Alpha family, no revisions or variants - Alpha is bi-endian, use endianness auto-detection described above. + Alpha is bi-endian, use endianness auto-detection implemented below. */ // #elif defined(__alpha__) || defined(_M_ALPHA) // # define Q_PROCESSOR_ALPHA @@ -85,7 +85,7 @@ ARM family, known revisions: V5, V6, and V7 ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to - auto-detection described above. + auto-detection implemented below. */ #if defined(__arm__) || defined(__TARGET_ARCH_ARM) # define Q_PROCESSOR_ARM @@ -154,7 +154,7 @@ /* Itanium (IA-64) family, no revisions or variants - Itanium is bi-endian, use endianness auto-detection described above. + Itanium is bi-endian, use endianness auto-detection implemented below. */ #elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) # define Q_PROCESSOR_IA64 @@ -163,7 +163,7 @@ /* MIPS family, known revisions: I, II, III, IV, 32, 64 - MIPS is bi-endian, use endianness auto-detection described above. + MIPS is bi-endian, use endianness auto-detection implemented below. */ #elif defined(__mips) || defined(__mips__) || defined(_M_MRX000) # define Q_PROCESSOR_MIPS @@ -188,7 +188,13 @@ # if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) # define Q_PROCESSOR_MIPS_64 # endif +# if defined(__MIPSEL__) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# elif defined(__MIPSEB__) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# else // Q_BYTE_ORDER not defined, use endianness auto-detection +# endif /* Power family, known variants: 32- and 64-bit @@ -197,7 +203,7 @@ See http://en.wikipedia.org/wiki/Power_Architecture and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg - Power is bi-endian, use endianness auto-detection described above. + Power is bi-endian, use endianness auto-detection implemented below. */ #elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \ || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \ @@ -225,7 +231,7 @@ /* SuperH family, optional revision: SH-4A - SuperH is bi-endian, use endianness auto-detection descrived above. + SuperH is bi-endian, use endianness auto-detection implemented below. */ // #elif defined(__sh__) // # define Q_PROCESSOR_SH @@ -249,6 +255,14 @@ #endif +/* + NOTE: + GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__ + and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer, + this code will properly detect your target byte order; if you are not, and + the __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then this + code will fail to detect the target byte order. +*/ // Some processors support either endian format, try to detect which we are using. #if !defined(Q_BYTE_ORDER) # if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN) diff --git a/src/corelib/global/qsysinfo.h b/src/corelib/global/qsysinfo.h index e6e207ec3d..74c8d1de7f 100644 --- a/src/corelib/global/qsysinfo.h +++ b/src/corelib/global/qsysinfo.h @@ -80,8 +80,6 @@ public: # error "Undefined byte order" # endif }; -#else -# error "Qt not configured correctly, please run configure" #endif #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) enum WinVersion { diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h new file mode 100644 index 0000000000..92bd949570 --- /dev/null +++ b/src/corelib/global/qtypetraits.h @@ -0,0 +1,420 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// ---- +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// +// Define a small subset of tr1 type traits. The traits we define are: +// is_integral +// is_floating_point +// is_pointer +// is_enum +// is_reference +// is_pod +// has_trivial_constructor +// has_trivial_copy +// has_trivial_assign +// has_trivial_destructor +// remove_const +// remove_volatile +// remove_cv +// remove_reference +// add_reference +// remove_pointer +// is_same +// is_convertible +// We can add more type traits as required. + +// Changes from the original implementation: +// - Move base types from template_util.h directly into this header. +// - Use Qt macros for long long type differences on Windows. +// - Enclose in QtPrivate namespace. + +#ifndef QTYPETRAITS_H +#define QTYPETRAITS_H + +#include <utility> // For pair +#include "QtCore/qglobal.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QtPrivate { + +// Types small_ and big_ are guaranteed such that sizeof(small_) < +// sizeof(big_) +typedef char small_; + +struct big_ { + char dummy[2]; +}; + +// Identity metafunction. +template <class T> +struct identity_ { + typedef T type; +}; + +// integral_constant, defined in tr1, is a wrapper for an integer +// value. We don't really need this generality; we could get away +// with hardcoding the integer type to bool. We use the fully +// general integer_constant for compatibility with tr1. + +template<class T, T v> +struct integral_constant { + static const T value = v; + typedef T value_type; + typedef integral_constant<T, v> type; +}; + +template <class T, T v> const T integral_constant<T, v>::value; + + +// Abbreviations: true_type and false_type are structs that represent boolean +// true and false values. Also define the boost::mpl versions of those names, +// true_ and false_. +typedef integral_constant<bool, true> true_type; +typedef integral_constant<bool, false> false_type; +typedef true_type true_; +typedef false_type false_; + +// if_ is a templatized conditional statement. +// if_<cond, A, B> is a compile time evaluation of cond. +// if_<>::type contains A if cond is true, B otherwise. +template<bool cond, typename A, typename B> +struct if_{ + typedef A type; +}; + +template<typename A, typename B> +struct if_<false, A, B> { + typedef B type; +}; + + +// type_equals_ is a template type comparator, similar to Loki IsSameType. +// type_equals_<A, B>::value is true iff "A" is the same type as "B". +// +// New code should prefer base::is_same, defined in base/type_traits.h. +// It is functionally identical, but is_same is the standard spelling. +template<typename A, typename B> +struct type_equals_ : public false_ { +}; + +template<typename A> +struct type_equals_<A, A> : public true_ { +}; + +// and_ is a template && operator. +// and_<A, B>::value evaluates "A::value && B::value". +template<typename A, typename B> +struct and_ : public integral_constant<bool, (A::value && B::value)> { +}; + +// or_ is a template || operator. +// or_<A, B>::value evaluates "A::value || B::value". +template<typename A, typename B> +struct or_ : public integral_constant<bool, (A::value || B::value)> { +}; + +template <class T> struct is_integral; +template <class T> struct is_floating_point; +template <class T> struct is_pointer; +// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +// is_enum uses is_convertible, which is not available on MSVC. +template <class T> struct is_enum; +#endif +template <class T> struct is_reference; +template <class T> struct is_pod; +template <class T> struct has_trivial_constructor; +template <class T> struct has_trivial_copy; +template <class T> struct has_trivial_assign; +template <class T> struct has_trivial_destructor; +template <class T> struct remove_const; +template <class T> struct remove_volatile; +template <class T> struct remove_cv; +template <class T> struct remove_reference; +template <class T> struct add_reference; +template <class T> struct remove_pointer; +template <class T, class U> struct is_same; +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +template <class From, class To> struct is_convertible; +#endif + +// is_integral is false except for the built-in integer types. A +// cv-qualified type is integral if and only if the underlying type is. +template <class T> struct is_integral : false_type { }; +template<> struct is_integral<bool> : true_type { }; +template<> struct is_integral<char> : true_type { }; +template<> struct is_integral<unsigned char> : true_type { }; +template<> struct is_integral<signed char> : true_type { }; +#if defined(_MSC_VER) +// wchar_t is not by default a distinct type from unsigned short in +// Microsoft C. +// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx +template<> struct is_integral<__wchar_t> : true_type { }; +#else +template<> struct is_integral<wchar_t> : true_type { }; +#endif +template<> struct is_integral<short> : true_type { }; +template<> struct is_integral<unsigned short> : true_type { }; +template<> struct is_integral<int> : true_type { }; +template<> struct is_integral<unsigned int> : true_type { }; +template<> struct is_integral<long> : true_type { }; +template<> struct is_integral<unsigned long> : true_type { }; +#if defined(Q_OS_WIN) && !defined(Q_CC_GNU) +template<> struct is_integral<__int64> : true_type { }; +template<> struct is_integral<unsigned __int64> : true_type { }; +#else +template<> struct is_integral<long long> : true_type { }; +template<> struct is_integral<unsigned long long> : true_type { }; +#endif +template <class T> struct is_integral<const T> : is_integral<T> { }; +template <class T> struct is_integral<volatile T> : is_integral<T> { }; +template <class T> struct is_integral<const volatile T> : is_integral<T> { }; + +// is_floating_point is false except for the built-in floating-point types. +// A cv-qualified type is integral if and only if the underlying type is. +template <class T> struct is_floating_point : false_type { }; +template<> struct is_floating_point<float> : true_type { }; +template<> struct is_floating_point<double> : true_type { }; +template<> struct is_floating_point<long double> : true_type { }; +template <class T> struct is_floating_point<const T> + : is_floating_point<T> { }; +template <class T> struct is_floating_point<volatile T> + : is_floating_point<T> { }; +template <class T> struct is_floating_point<const volatile T> + : is_floating_point<T> { }; + +// is_pointer is false except for pointer types. A cv-qualified type (e.g. +// "int* const", as opposed to "int const*") is cv-qualified if and only if +// the underlying type is. +template <class T> struct is_pointer : false_type { }; +template <class T> struct is_pointer<T*> : true_type { }; +template <class T> struct is_pointer<const T> : is_pointer<T> { }; +template <class T> struct is_pointer<volatile T> : is_pointer<T> { }; +template <class T> struct is_pointer<const volatile T> : is_pointer<T> { }; + +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + +namespace internal { + +template <class T> struct is_class_or_union { + template <class U> static small_ tester(void (U::*)()); + template <class U> static big_ tester(...); + static const bool value = sizeof(tester<T>(0)) == sizeof(small_); +}; + +// is_convertible chokes if the first argument is an array. That's why +// we use add_reference here. +template <bool NotUnum, class T> struct is_enum_impl + : is_convertible<typename add_reference<T>::type, int> { }; + +template <class T> struct is_enum_impl<true, T> : false_type { }; + +} // namespace internal + +// Specified by TR1 [4.5.1] primary type categories. + +// Implementation note: +// +// Each type is either void, integral, floating point, array, pointer, +// reference, member object pointer, member function pointer, enum, +// union or class. Out of these, only integral, floating point, reference, +// class and enum types are potentially convertible to int. Therefore, +// if a type is not a reference, integral, floating point or class and +// is convertible to int, it's a enum. Adding cv-qualification to a type +// does not change whether it's an enum. +// +// Is-convertible-to-int check is done only if all other checks pass, +// because it can't be used with some types (e.g. void or classes with +// inaccessible conversion operators). +template <class T> struct is_enum + : internal::is_enum_impl< + is_same<T, void>::value || + is_integral<T>::value || + is_floating_point<T>::value || + is_reference<T>::value || + internal::is_class_or_union<T>::value, + T> { }; + +template <class T> struct is_enum<const T> : is_enum<T> { }; +template <class T> struct is_enum<volatile T> : is_enum<T> { }; +template <class T> struct is_enum<const volatile T> : is_enum<T> { }; + +#endif + +// is_reference is false except for reference types. +template<typename T> struct is_reference : false_type {}; +template<typename T> struct is_reference<T&> : true_type {}; + + +// We can't get is_pod right without compiler help, so fail conservatively. +// We will assume it's false except for arithmetic types, enumerations, +// pointers and cv-qualified versions thereof. Note that std::pair<T,U> +// is not a POD even if T and U are PODs. +template <class T> struct is_pod + : integral_constant<bool, (is_integral<T>::value || + is_floating_point<T>::value || +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) + // is_enum is not available on MSVC. + is_enum<T>::value || +#endif + is_pointer<T>::value)> { }; +template <class T> struct is_pod<const T> : is_pod<T> { }; +template <class T> struct is_pod<volatile T> : is_pod<T> { }; +template <class T> struct is_pod<const volatile T> : is_pod<T> { }; + + +// We can't get has_trivial_constructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// constructors. (3) array of a type with a trivial constructor. +// (4) const versions thereof. +template <class T> struct has_trivial_constructor : is_pod<T> { }; +template <class T, class U> struct has_trivial_constructor<std::pair<T, U> > + : integral_constant<bool, + (has_trivial_constructor<T>::value && + has_trivial_constructor<U>::value)> { }; +template <class A, int N> struct has_trivial_constructor<A[N]> + : has_trivial_constructor<A> { }; +template <class T> struct has_trivial_constructor<const T> + : has_trivial_constructor<T> { }; + +// We can't get has_trivial_copy right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial copy constructor. +// (4) const versions thereof. +template <class T> struct has_trivial_copy : is_pod<T> { }; +template <class T, class U> struct has_trivial_copy<std::pair<T, U> > + : integral_constant<bool, + (has_trivial_copy<T>::value && + has_trivial_copy<U>::value)> { }; +template <class A, int N> struct has_trivial_copy<A[N]> + : has_trivial_copy<A> { }; +template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { }; + +// We can't get has_trivial_assign right without compiler help, so fail +// conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial copy +// constructors. (3) array of a type with a trivial assign constructor. +template <class T> struct has_trivial_assign : is_pod<T> { }; +template <class T, class U> struct has_trivial_assign<std::pair<T, U> > + : integral_constant<bool, + (has_trivial_assign<T>::value && + has_trivial_assign<U>::value)> { }; +template <class A, int N> struct has_trivial_assign<A[N]> + : has_trivial_assign<A> { }; + +// We can't get has_trivial_destructor right without compiler help, so +// fail conservatively. We will assume it's false except for: (1) types +// for which is_pod is true. (2) std::pair of types with trivial +// destructors. (3) array of a type with a trivial destructor. +// (4) const versions thereof. +template <class T> struct has_trivial_destructor : is_pod<T> { }; +template <class T, class U> struct has_trivial_destructor<std::pair<T, U> > + : integral_constant<bool, + (has_trivial_destructor<T>::value && + has_trivial_destructor<U>::value)> { }; +template <class A, int N> struct has_trivial_destructor<A[N]> + : has_trivial_destructor<A> { }; +template <class T> struct has_trivial_destructor<const T> + : has_trivial_destructor<T> { }; + +// Specified by TR1 [4.7.1] +template<typename T> struct remove_const { typedef T type; }; +template<typename T> struct remove_const<T const> { typedef T type; }; +template<typename T> struct remove_volatile { typedef T type; }; +template<typename T> struct remove_volatile<T volatile> { typedef T type; }; +template<typename T> struct remove_cv { + typedef typename remove_const<typename remove_volatile<T>::type>::type type; +}; + + +// Specified by TR1 [4.7.2] Reference modifications. +template<typename T> struct remove_reference { typedef T type; }; +template<typename T> struct remove_reference<T&> { typedef T type; }; + +template <typename T> struct add_reference { typedef T& type; }; +template <typename T> struct add_reference<T&> { typedef T& type; }; + +// Specified by TR1 [4.7.4] Pointer modifications. +template<typename T> struct remove_pointer { typedef T type; }; +template<typename T> struct remove_pointer<T*> { typedef T type; }; +template<typename T> struct remove_pointer<T* const> { typedef T type; }; +template<typename T> struct remove_pointer<T* volatile> { typedef T type; }; +template<typename T> struct remove_pointer<T* const volatile> { + typedef T type; }; + +// Specified by TR1 [4.6] Relationships between types +template<typename T, typename U> struct is_same : public false_type { }; +template<typename T> struct is_same<T, T> : public true_type { }; + +// Specified by TR1 [4.6] Relationships between types +#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +namespace internal { + +// This class is an implementation detail for is_convertible, and you +// don't need to know how it works to use is_convertible. For those +// who care: we declare two different functions, one whose argument is +// of type To and one with a variadic argument list. We give them +// return types of different size, so we can use sizeof to trick the +// compiler into telling us which function it would have chosen if we +// had called it with an argument of type From. See Alexandrescu's +// _Modern C++ Design_ for more details on this sort of trick. + +template <typename From, typename To> +struct ConvertHelper { + static small_ Test(To); + static big_ Test(...); + static From Create(); +}; +} // namespace internal + +// Inherits from true_type if From is convertible to To, false_type otherwise. +template <typename From, typename To> +struct is_convertible + : integral_constant<bool, + sizeof(internal::ConvertHelper<From, To>::Test( + internal::ConvertHelper<From, To>::Create())) + == sizeof(small_)> { +}; +#endif + +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QTYPETRAITS_H |