From: Václav Slavík Date: Mon, 25 Oct 2010 09:43:00 +0000 (+0000) Subject: Make wxMin, wxMax and wxClip template functions. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a52475807e0521097764e5fe4cc738d80f13baad?hp=1f4c7e791bed162fc1b6d3bc03d875f1b9790c15 Make wxMin, wxMax and wxClip template functions. Previously used macro's arguments were evaluated twice, but there were many occurences of their use in our code that didn't account for this and used expensive-to-evaluate arguments as if they were functions. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65920 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- 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