diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 3e92103acd..e5fe973509 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -554,6 +554,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/zstream.h wx/meta/convertible.h wx/meta/if.h + wx/meta/implicitconversion.h wx/meta/int2type.h wx/meta/movable.h wx/meta/pod.h diff --git a/include/wx/meta/implicitconversion.h b/include/wx/meta/implicitconversion.h new file mode 100644 index 0000000000..8e65fbcc12 --- /dev/null +++ b/include/wx/meta/implicitconversion.h @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/meta/implicitconversion.h +// Purpose: Determine resulting type from implicit conversion +// Author: Vaclav Slavik +// Created: 2010-10-22 +// RCS-ID: $Id$ +// Copyright: (c) 2010 Vaclav Slavik +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_META_IMPLICITCONVERSION_H_ +#define _WX_META_IMPLICITCONVERSION_H_ + +#include "wx/defs.h" +#include "wx/meta/if.h" + +// C++ hierarchy of data types is: +// +// Long double (highest) +// Double +// Float +// Unsigned long int +// Long int +// Unsigned int +// Int (lowest) +// +// Types lower in the hierarchy are converted into ones higher up if both are +// involved e.g. in arithmetic expressions. + +namespace wxPrivate +{ + +template +struct TypeHierarchy +{ + // consider unknown types (e.g. objects, pointers) to be of highest + // level, always convert to them if they occur + enum { level = 9999 }; +}; + +#define WX_TYPE_HIERARCHY_LEVEL(level_num, type) \ + template<> struct TypeHierarchy \ + { \ + enum { level = level_num }; \ + }; + +WX_TYPE_HIERARCHY_LEVEL( 1, char); +WX_TYPE_HIERARCHY_LEVEL( 2, unsigned char); +WX_TYPE_HIERARCHY_LEVEL( 3, short); +WX_TYPE_HIERARCHY_LEVEL( 4, unsigned short); +WX_TYPE_HIERARCHY_LEVEL( 5, int); +WX_TYPE_HIERARCHY_LEVEL( 6, unsigned int); +WX_TYPE_HIERARCHY_LEVEL( 7, long); +WX_TYPE_HIERARCHY_LEVEL( 8, unsigned long); +#ifdef wxLongLong_t +WX_TYPE_HIERARCHY_LEVEL( 9, wxLongLong_t); +WX_TYPE_HIERARCHY_LEVEL(10, wxULongLong_t); +#endif +WX_TYPE_HIERARCHY_LEVEL(11, float); +WX_TYPE_HIERARCHY_LEVEL(12, double); +WX_TYPE_HIERARCHY_LEVEL(13, long double); + +#if wxWCHAR_T_IS_REAL_TYPE + #if SIZEOF_WCHAR_T == SIZEOF_SHORT + template<> struct TypeHierarchy : public TypeHierarchy {}; + #elif SIZEOF_WCHAR_T == SIZEOF_INT + template<> struct TypeHierarchy : public TypeHierarchy {}; + #elif SIZEOF_WCHAR_T == SIZEOF_LONG + template<> struct TypeHierarchy : public TypeHierarchy {}; + #else + #error "weird wchar_t size, please update this code" + #endif +#endif + +#undef WX_TYPE_HIERARCHY_LEVEL + +} // namespace wxPrivate + +// Helper to determine resulting type of implicit conversion in +// an expression with two arithmetic types. +template +struct wxImplicitConversionType +{ + typedef typename wxIf + < + // if T2 is "higher" type, convert to it + (int)wxPrivate::TypeHierarchy::level < (int)wxPrivate::TypeHierarchy::level, + T2, + // otherwise use T1 + T1 + >::value + value; +}; + + +template +struct wxImplicitConversionType3 : public wxImplicitConversionType< + T1, + typename wxImplicitConversionType::value> +{ +}; + +#endif // _WX_META_IMPLICITCONVERSION_H_ diff --git a/include/wx/utils.h b/include/wx/utils.h index 78f29a0063..96d1a9acd1 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -20,6 +20,7 @@ #include "wx/list.h" #include "wx/filefn.h" #include "wx/hashmap.h" +#include "wx/meta/implicitconversion.h" #if wxUSE_GUI #include "wx/gdicmn.h" @@ -55,12 +56,33 @@ class WXDLLIMPEXP_FWD_CORE wxWindow; class WXDLLIMPEXP_FWD_CORE wxWindowList; // ---------------------------------------------------------------------------- -// Macros +// Arithmetic functions // ---------------------------------------------------------------------------- -#define wxMax(a,b) (((a) > (b)) ? (a) : (b)) -#define wxMin(a,b) (((a) < (b)) ? (a) : (b)) -#define wxClip(a,b,c) (((a) < (b)) ? (b) : (((a) > (c)) ? (c) : (a))) +template +inline typename wxImplicitConversionType::value +wxMax(T1 a, T2 b) +{ + return (a > b) ? a : b; +} + +template +inline typename wxImplicitConversionType::value +wxMin(T1 a, T2 b) +{ + return (a < b) ? a : b; +} + +template +inline typename wxImplicitConversionType3::value +wxClip(T1 a, T2 b, T3 c) +{ + return (a < b) ? b : ((a > c) ? c : a); +} + +// ---------------------------------------------------------------------------- +// wxMemorySize +// ---------------------------------------------------------------------------- // wxGetFreeMemory can return huge amount of memory on 32-bit platforms as well // so to always use long long for its result type on all platforms which