1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/meta/convertible.h
3 // Purpose:     Test if types are convertible
4 // Author:      Arne Steinarson
5 // Created:     2008-01-10
6 // Copyright:   (c) 2008 Arne Steinarson
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 #ifndef _WX_META_CONVERTIBLE_H_
11 #define _WX_META_CONVERTIBLE_H_
12 
13 //
14 // Introduce an extra class to make this header compilable with g++3.2
15 //
16 template <class D, class B>
17 struct wxConvertibleTo_SizeHelper
18 {
19     static char Match(B* pb);
20     static int  Match(...);
21 };
22 
23 // Helper to decide if an object of type D is convertible to type B (the test
24 // succeeds in particular when D derives from B)
25 template <class D, class B>
26 struct wxConvertibleTo
27 {
28     enum
29     {
30         value =
31             sizeof(wxConvertibleTo_SizeHelper<D,B>::Match(static_cast<D*>(NULL)))
32             ==
33             sizeof(char)
34     };
35 };
36 
37 // This is similar to wxConvertibleTo, except that when using a C++11 compiler,
38 // the case of D deriving from B non-publicly will be detected and the correct
39 // value (false) will be deduced instead of getting a compile-time error as
40 // with wxConvertibleTo. For pre-C++11 compilers there is no difference between
41 // this helper and wxConvertibleTo.
42 template <class D, class B>
43 struct wxIsPubliclyDerived
44 {
45     enum
46     {
47 #if __cplusplus >= 201103 || (defined(_MSC_VER) && _MSC_VER >= 1600)
48         // If C++11 is available we use this, as on most compilers it's a
49         // built-in and will be evaluated at compile-time.
50         value = std::is_base_of<B, D>::value && std::is_convertible<D*, B*>::value
51 #else
52         // When not using C++11, we fall back to wxConvertibleTo, which fails
53         // at compile-time if D doesn't publicly derive from B.
54         value = wxConvertibleTo<D, B>::value
55 #endif
56     };
57 };
58 
59 #endif // _WX_META_CONVERTIBLE_H_
60 
61