Welcome to mirror list, hosted at ThFree Co, Russian Federation.

type_traits.hpp « inc « Runtime « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 463de37333b406943beecb39460b5fde93f830f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// type_traits.hpp
//
// Type trait metaprogramming utilities.
//

#ifndef __TYPE_TRAITS_HPP__
#define __TYPE_TRAITS_HPP__

#include "CommonTypes.h"

namespace type_traits
{

namespace imp
{

struct true_type { static const bool value = true; };
struct false_type { static const bool value = false; };

////////////////////////////////////////////////////////////////////////////////
// Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
//

template <class T, class U>
struct conversion_helper
{
    typedef char Small;
    struct Big { char dummy[2]; };
    static Big   Test(...);
    static Small Test(U);
    static T MakeT();
};

////////////////////////////////////////////////////////////////////////////////
// class template conversion
// Figures out the conversion relationships between two types
// Invocations (T and U are types):
// a) conversion<T, U>::exists
// returns (at compile time) true if there is an implicit conversion from T
// to U (example: Derived to Base)
// b) conversion<T, U>::exists2Way
// returns (at compile time) true if there are both conversions from T
// to U and from U to T (example: int to char and back)
// c) conversion<T, U>::sameType
// returns (at compile time) true if T and U represent the same type
//
// NOTE: might not work if T and U are in a private inheritance hierarchy.
//

template <class T, class U>
struct conversion
{
    typedef imp::conversion_helper<T, U> H;
    static const bool exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT())));
    static const bool exists2Way = exists && conversion<U, T>::exists;
    static const bool sameType = false;
};

template <class T>
struct conversion<T, T>    
{
    static const bool exists = true;
    static const bool exists2Way = true;
    static const bool sameType = true;
};

template <class T>
struct conversion<void, T>    
{
    static const bool exists = false;
    static const bool exists2Way = false;
    static const bool sameType = false;
};

template <class T>
struct conversion<T, void>    
{
    static const bool exists = false;
    static const bool exists2Way = false;
    static const bool sameType = false;
};

template <>
struct conversion<void, void>    
{
    static const bool exists = true;
    static const bool exists2Way = true;
    static const bool sameType = true;
};

template <bool>
struct is_base_of_helper;

template <>
struct is_base_of_helper<true> : public true_type {} ;

template <>
struct is_base_of_helper<false> : public false_type {} ;

}// imp

////////////////////////////////////////////////////////////////////////////////
// is_base_of::value is typedefed to be true if TDerived derives from TBase
// and false otherwise.
//
//
// NOTE: use TR1 type_traits::is_base_of when available.
//
#ifdef _MSC_VER

template <typename TBase, typename TDerived>
struct is_base_of : public imp::is_base_of_helper<__is_base_of( TBase, TDerived)> {};

#else

// Note that we need to compare pointer types here, since conversion of types by-value
// just tells us whether or not an implicit conversion constructor exists. We handle
// type parameters that are already pointers specially; see below.
template <typename TBase, typename TDerived>
struct is_base_of : public imp::is_base_of_helper<imp::conversion<TDerived *, TBase *>::exists> {};

// Specialization to handle type parameters that are already pointers.
template <typename TBase, typename TDerived>
struct is_base_of<TBase *, TDerived *> : public imp::is_base_of_helper<imp::conversion<TDerived *, TBase *>::exists> {};

// Specialization to handle invalid mixing of pointer types.
template <typename TBase, typename TDerived>
struct is_base_of<TBase *, TDerived> : public imp::false_type {};

// Specialization to handle invalid mixing of pointer types.
template <typename TBase, typename TDerived>
struct is_base_of<TBase, TDerived *> : public imp::false_type {};

#endif

////////////////////////////////////////////////////////////////////////////////
// Remove const qualifications, if any. Access using remove_const::type
//
template <typename T> struct remove_const { typedef T type; };
template <typename T> struct remove_const<T const> { typedef T type; };

////////////////////////////////////////////////////////////////////////////////
// is_signed::value is true if T is a signed integral type, false otherwise.
//
template <typename T>
struct is_signed { static const bool value = (static_cast<T>(-1) < 0); };

}

////////////////////////////////////////////////////////////////////////////////
// These are related to type traits, but they are more like asserts of type
// traits in that the result is that either the compiler does or does not
// produce an error.
//
namespace type_constraints
{

////////////////////////////////////////////////////////////////////////////////
// derived_from will produce a compiler error if TDerived does not
// derive from TBase.
//
// NOTE: use TR1 type_traits::is_base_of when available.
//

template<class TBase, class TDerived> struct is_base_of
{
    is_base_of()
    {
        static_assert((type_traits::is_base_of<TBase, TDerived>::value),
                      "is_base_of() constraint violation: TDerived does not derive from TBase");
    }
};

}; // namespace type_constraints

namespace rh { namespace std
{
    // Import some select components of the STL

    // TEMPLATE FUNCTION for_each
    template<class _InIt, class _Fn1>
    inline
    _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
    {   // perform function for each element
        for (; _First != _Last; ++_First)
            _Func(*_First);
        return (_Func);
    }

    template<class _InIt, class _Ty>
    inline
    _InIt find(_InIt _First, _InIt _Last, const _Ty& _Val)
    {   // find first matching _Val
        for (; _First != _Last; ++_First)
            if (*_First == _Val)
                break;
        return (_First);
    }

    template<class _InIt, class _Pr>
    inline
    _InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
    {   // find first satisfying _Pred
        for (; _First != _Last; ++_First)
            if (_Pred(*_First))
                break;
        return (_First);
    }

    template<class _InIt, class _Ty>
    inline
    bool exists(_InIt _First, _InIt _Last, const _Ty& _Val)
    {
        return find(_First, _Last, _Val) != _Last;
    }

    template<class _InIt, class _Pr>
    inline
    bool exists_if(_InIt _First, _InIt _Last, _Pr _Pred)
    {
        return find_if(_First, _Last, _Pred) != _Last;
    }

    template<class _InIt, class _Ty>
    inline
    UIntNative count(_InIt _First, _InIt _Last, const _Ty& _Val)
    {
        UIntNative _Ret = 0;
        for (; _First != _Last; _First++)
            if (*_First == _Val)
                ++_Ret;
        return _Ret;
    }

    template<class _InIt, class _Pr>
    inline
    UIntNative count_if(_InIt _First, _InIt _Last, _Pr _Pred)
    {
        UIntNative _Ret = 0;
        for (; _First != _Last; _First++)
            if (_Pred(*_First))
                ++_Ret;
        return _Ret;
    }

    // Forward declaration, each collection requires specialization
    template<class _FwdIt, class _Ty>
    inline
    _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val);
} // namespace std
} // namespace rh

#if 0

// -----------------------------------------------------------------
// Holding place for unused-but-possibly-useful-in-the-future code.

// -------------------------------------------------
// This belongs in type_traits.hpp

//
// is_pointer::value is true if the type is a pointer, false otherwise
//
template <typename T> struct is_pointer : public false_type {};
template <typename T> struct is_pointer<T *> : public true_type {};

//
// Remove pointer from type, if it has one. Use remove_pointer::type
// Further specialized in daccess.h
//
template <typename T> struct remove_pointer { typedef T type; };
template <typename T> struct remove_pointer<T *> { typedef T type; };

// -------------------------------------------------
// This belongs in daccess.h

namespace type_traits
{

//
// is_pointer::value is true if the type is a pointer, false otherwise
// specialized from type_traits.hpp
//
template <typename T> struct is_pointer<typename __DPtr<T> > : public type_traits::true_type {};

//
// remove_pointer::type is T with one less pointer qualification, if it had one.
// specialized from type_traits.hpp
//
template <typename T> struct remove_pointer<typename __DPtr<T> > { typedef T type; };

} // type_traits

namespace dac
{

//
// is_dptr::value is true if T is a __DPtr, false otherwise.
// This is a partial specialization case for the positive case.
//
//template <typename T> struct is_dptr<typename __DPtr<T> > : public type_traits::true_type {};

}

#endif

#endif