InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MetaProgramming.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Mat Marcus and Jesse Jones
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //========================================================================================
23 
24 #ifndef __MetaProgramming__
25 #define __MetaProgramming__
26 
27 #if WINDOWS
28 #endif
29 
30 #ifdef WINDOWS
31 #define HAS_PARTIAL_SPECIALIZATION 0
32 #else
33 #define HAS_PARTIAL_SPECIALIZATION 1
34 #endif
35 
36 
37 namespace K2Meta {
38 
39 // ----- IF -----
40 struct FirstPicker {
41  template <class First, class Second>
42  struct Result {
43  typedef First RET;
44  };
45 };
46 
47 struct SecondPicker {
48  template <class First, class Second>
49  struct Result {
50  typedef Second RET;
51  };
52 };
53 
54 template <bool condition>
55 struct BoolToPicker {
56  typedef SecondPicker RET;
57 };
58 
59 template <>
60 struct BoolToPicker<true> {
61  typedef FirstPicker RET;
62 };
63 
64 template <bool condition, class IfType, class ElseType>
65 class IF { // $$ can simplify this quite a bit once MSVC supports partial specialization
66  typedef typename BoolToPicker<condition>::RET Picker;
67 public:
68  typedef typename Picker::template Result<IfType, ElseType>::RET RET;
69 };
70 
71 
72 
73 struct META_FALSE {
74  enum {RET = false};
75 };
76 
77 struct META_TRUE {
78  enum {RET = true};
79 };
80 
81 template <bool condition>
82 struct BOOL_TO_TYPE {
83  typedef typename IF<condition, META_TRUE, META_FALSE>::RET RET;
84 };
85 
86 // ----- META_ASSERT -----
87 struct ValidCode {}; // type used by code that is OK
88 
89 template <bool PREDICATE, typename ERR_MESG> // metafunction that returns a type that cannot be instantiated if the predicate is true
91 {
92  typedef typename K2Meta::IF<PREDICATE, ValidCode, ERR_MESG>::RET RET;
93 };
94 
95 template <bool PREDICATE, typename ERR_MESG> // causes a compile time error if the predicate is false
96 void META_ASSERT()
97 {
98  typename ASSERT_SELECTOR<PREDICATE, ERR_MESG>::RET checker;
99  (void) checker;
100 }
101 
102 
103 // ----- IS_POD -----
104 // see K2TypeTraits.h
105 
106 
107 // ----- IS_PTR -----
108 #if HAS_PARTIAL_SPECIALIZATION
109  template <typename T>
110  struct IS_PTR {
111  enum { RET = false};
112  };
113 
114  template <typename T>
115  struct IS_PTR<T*> {
116  enum { RET = true };
117  };
118 
119  template <typename T>
120  struct IS_PTR<T* const> {
121  enum { RET = true };
122  };
123 
124 #else
125  struct IsPtrConverter { // allows IsPtr to test only ptrs not classes with conversion operators
126  IsPtrConverter(const volatile void* const) {}
127  };
128 
129  char IsPtr(IsPtrConverter);
130  int IsPtr(...);
131 
132  template <typename T>
133  struct IS_PTR {
134  static T t;
135  enum { RET = (sizeof(IsPtr(t)) == 1) };
136  };
137 #endif
138 
139 
140 // ----- IF_IS_PTR -----
141 template <class T, class IfType, class ElseType>
142 struct IF_IS_PTR
143 {
144  typedef typename IF<IS_PTR<T>::RET, IfType, ElseType>::RET RET;
145 };
146 
147 
148 // ----- IS_SAME_TYPE -----
149 #if HAS_PARTIAL_SPECIALIZATION
150  template <typename T, typename U> struct IS_SAME_TYPE {enum {RET = false};};
151  template <typename T> struct IS_SAME_TYPE<T, T> {enum {RET = true};};
152 
153 #else
154  int IsSameType(...);
155 
156  template <typename T>
157  char IsSameType(T, T);
158 
159  template <typename T, typename U>
160  struct IS_SAME_TYPE {
161  static T t;
162  static U u;
163  enum {RET = (sizeof(IsSameType(t, u)) == 1)};
164  };
165 #endif
166 
167 
168 #if 0
169 // Metrowerks sizeof till too buggy
170 #include <boost/type_traits.hpp>
171 // ----- IS_CONVERTIBLE -----
172  // Thanks to A. Alexandrescu for the idea
173  template <typename From, typename To>
174  struct IS_CONVERTIBLE { // can T be converted to U?
175  static char IsConvertible(To);
176  static int IsConvertible(...);
177  static From t;
178  static const int RET = sizeof(IsConvertible(t)) == 1;
179  };
180 
181  // Metrowerks sizeof bug workaround
182  template <typename From, typename To>
183  const int IS_CONVERTIBLE<From, To>::RET = sizeof(IsConvertible(t)) == 1;
184 
185 // ----- IS_ENUM -----
186 template <typename T> struct IS_ENUM
187 {
188 //Copyright for IS_ENUM
189 // (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
190 // Permission to copy, use, modify, sell and
191 // distribute this software is granted provided this copyright notice appears
192 // in all copies. This software is provided "as is" without express or implied
193 // warranty, and with no claim as to its suitability for any purpose.
194 private:
195  typedef typename ::boost::add_reference<T>::type r_type;
196  enum { NOT_ARITH = !(::boost::is_arithmetic<T>::value) };
197  enum { NOT_REF = !(::boost::is_reference<T>::value)};
198  enum { INT_CONVERT = (K2Meta::IS_CONVERTIBLE<r_type, ::boost::detail::int_convertible>::RET)};
199 
200 public:
201  enum { RET = NOT_ARITH && NOT_REF && INT_CONVERT};
202 };
203 
204 #endif
205 } // namespace K2Meta
206 
207 #endif //__MetaProgramming__