1 // xutility stl/clr header
2 #ifndef _CLI_XUTILITY_
3  #define _CLI_XUTILITY_
4
5 #ifndef __cplusplus_cli
6  #error STL/CLR can be used only in code compiled /clr, clr:pure, or /clr:safe
7 #endif /* __cplusplus_cli */
8
9 #using <Microsoft.VisualC.STLCLR.dll>
10
11 #ifdef _M_CEE_SAFE
12 #else /* _M_CEE_SAFE */
13  #include <cstddef>        // for ptrdiff_t, size_t
14  #include <xutility>    // for iterator tags
15 #endif /* _M_CEE_SAFE */
16
17 #define _STLCLR_FIELD_ACCESS    internal
18 #define _STLCLR        Microsoft::VisualC::StlClr::
19
20 #define MAX_CONTAINER_SIZE    ((int)((unsigned int)(-1) >> 1))
21
22 namespace cliext {
23 //
24 // TEMPLATE METAPROGRAMMING AIDS
25 //
26 //
27 // TEMPLATE VALUE CLASS is_handle
28 //
29 template<typename _Value_t>
30     value class is_handle
31     {    // identify non-handle type
32 public:
33     static const bool value = false;
34     };
35
36 template<typename _Value_t>
37     value class is_handle<_Value_t^>
38     {    // identify handle type
39 public:
40     static const bool value = true;
41     };
42
43 //
44 // TEMPLATE VALUE CLASS _Container_traits
45 //
46 template<typename _Cont_t>
47     value class _Container_traits
48     {    // define types associated with a container
49 public:
50     typedef typename _Cont_t::generic_container generic_container;
51     typedef typename _Cont_t::generic_container^ generic_container_handle;
52     };
53
54 template<typename _Cont_t>
55     value class _Container_traits<_Cont_t^>
56     {    // define type associated with a container handle
57 public:
58     typedef typename _Cont_t::generic_container generic_container;
59     typedef typename _Cont_t::generic_container^ generic_container_handle;
60     };
61
62 //
63 // TEMPLATE VALUE CLASS _Dehandle
64 //
65 template<typename _Value_t>
66     value class _Dehandle
67     {    // define non-handle type
68 public:
69     typedef _Value_t type;
70     };
71
72 template<typename _Value_t>
73     value class _Dehandle<_Value_t^>
74     {    // define type with handle removed
75 public:
76     typedef _Value_t type;
77     };
78
79 //
80 // TEMPLATE CLASS _Cont_make_value
81 //
82 template<typename _Value_t,
83     bool _Is_ref>
84     ref class _Cont_make_value
85     {    // make a non-ref value
86 public:
87     static _Value_t make_value(_Value_t% _Val)
88         {    // just return value
89         return (_Val);
90         }
91
92     static void unmake_value(_Value_t%)
93         {    // just do nothing
94         }
95     };
96
97 template<typename _Value_t>
98     ref class _Cont_make_value<_Value_t, true>
99     {    // make a ref value
100 public:
101     static _Value_t make_value(_Value_t% _Val)
102         {    // return copy of value
103         return (gcnew typename _Dehandle<_Value_t>::type(_Val));
104         }
105
106     static void unmake_value(_Value_t% _Val)
107         {    // delete object designated by handle value
108         delete _Val;
109         }
110     };
111
112 //
113 // TEMPLATE VALUE CLASS _Generic_type
114 //
115 template<typename _Value_t,
116     bool isref = !is_handle<_Value_t>::value && __is_ref_class(_Value_t)>
117     value class _Generic_type;
118
119 template<typename _Value_t>
120     value class _Generic_type<_Value_t, false>
121     {    // define a non-ref type
122 public:
123     typedef _Value_t type;
124     };
125
126 template<typename _Value_t>
127     value class _Generic_type<_Value_t, true>
128     {    // define a ref type
129 public:
130     typedef _Value_t^ type;
131     };
132
133 //
134 // TEMPLATE FUNCTION _Handle_alloc
135 //
136 template<typename Mycont> inline
137     Mycont^ _Handle_alloc(Mycont^)
138     {    // allocate a container, given its handle type
139     return (gcnew Mycont);
140     }
141
142 //
143 // TEMPLATE CLASS _Fix_handle
144 //
145 #define _FIX_HANDLE(to, from, val) \
146     cliext::_Fix_handle<to, from>::_Cvt(from(val))
147
148 template<typename _To_t,
149     typename _From_t>
150     ref class _Fix_handle
151     {    // add or remove handle as needed, default version
152 public:
153     static _To_t _Cvt(_From_t _Val)
154         {    // convert _Val
155         return (_To_t(_Val));
156         }
157     };
158
159 template<typename _To_t,
160     typename _From_t>
161     ref class _Fix_handle<_To_t^, _From_t>
162     {    // add or remove handle as needed, add version
163 public:
164     static _To_t^ _Cvt(_From_t _Val)
165         {    // convert _Val
166         return (gcnew _To_t(_Val));
167         }
168     };
169
170 template<typename _To_t,
171     typename _From_t>
172     ref class _Fix_handle<_To_t, _From_t^>
173     {    // add or remove handle as needed, remove version
174 public:
175     static _To_t _Cvt(_From_t^ _Val)
176         {    // convert _Val
177         return (*_Val);
178         }
179     };
180
181 template<typename _To_t,
182     typename _From_t>
183     ref class _Fix_handle<_To_t^, _From_t^>
184     {    // add or remove handle as needed, handles version
185 public:
186     static _To_t^ _Cvt(_From_t^ _Val)
187         {    // convert _Val
188         return (_Val);
189         }
190     };
191
192 //
193 // ITERATOR TAGS
194 //
195 ref class input_iterator_tag
196     {    // identifying tag for input iterators
197 public:
198     typedef input_iterator_tag _Mytype_t;
199
200     input_iterator_tag()
201         {    // default constructor
202         }
203
204     input_iterator_tag(input_iterator_tag%)
205         {    // copy constructor
206         }
207     };
208
209 ref class output_iterator_tag
210     {    // identifying tag for output iterators
211 public:
212     typedef output_iterator_tag _Mytype_t;
213
214     output_iterator_tag()
215         {    // default constructor
216         }
217
218     output_iterator_tag(output_iterator_tag%)
219         {    // copy constructor
220         }
221     };
222
223 ref class forward_iterator_tag
224     : public input_iterator_tag
225     {    // identifying tag for forward iterators
226 public:
227     typedef forward_iterator_tag _Mytype_t;
228
229     forward_iterator_tag()
230         {    // default constructor
231         }
232
233     forward_iterator_tag(forward_iterator_tag%)
234         {    // copy constructor
235         }
236     };
237
238 ref class bidirectional_iterator_tag
239     : public forward_iterator_tag
240     {    // identifying tag for bidirectional iterators
241 public:
242     typedef bidirectional_iterator_tag _Mytype_t;
243
244     bidirectional_iterator_tag()
245         {    // default constructor
246         }
247
248     bidirectional_iterator_tag(bidirectional_iterator_tag%)
249         {    // copy constructor
250         }
251     };
252
253 ref class random_access_iterator_tag
254     : public bidirectional_iterator_tag
255     {    // identifying tag for random-access iterators
256 public:
257     typedef random_access_iterator_tag _Mytype_t;
258
259     random_access_iterator_tag()
260         {    // default constructor
261         }
262
263     random_access_iterator_tag(random_access_iterator_tag%)
264         {    // copy constructor
265         }
266     };
267
268 ref class _Int_iterator_tag
269     {    // identifying tag for integer types, not an iterator
270 public:
271     typedef _Int_iterator_tag _Mytype_t;
272
273     _Int_iterator_tag()
274         {    // default constructor
275         }
276
277     _Int_iterator_tag(_Int_iterator_tag%)
278         {    // copy constructor
279         }
280     };
281
282 //
283 // REF CLASS _Map_iter_cat
284 //
285 template<typename _Cat>
286     ref class _Map_iter_cat
287     {    // map to argument
288 public:
289     typedef _Cat iterator_category;
290     };
291
292 #ifdef _M_CEE_SAFE
293 #else /* _M_CEE_SAFE */
294 template<>
295     ref class _Map_iter_cat<std::input_iterator_tag>
296     {    // map to managed tag
297 public:
298     typedef input_iterator_tag iterator_category;
299     };
300
301 template<>
302     ref class _Map_iter_cat<std::output_iterator_tag>
303     {    // map to managed tag
304 public:
305     typedef output_iterator_tag iterator_category;
306     };
307
308 template<>
309     ref class _Map_iter_cat<std::forward_iterator_tag>
310     {    // map to managed tag
311 public:
312     typedef forward_iterator_tag iterator_category;
313     };
314
315 template<>
316     ref class _Map_iter_cat<std::bidirectional_iterator_tag>
317     {    // map to managed tag
318 public:
319     typedef bidirectional_iterator_tag iterator_category;
320     };
321
322 template<>
323     ref class _Map_iter_cat<std::random_access_iterator_tag>
324     {    // map to managed tag
325 public:
326     typedef random_access_iterator_tag iterator_category;
327     };
328
329 template<>
330     ref class _Map_iter_cat<std::_Int_iterator_tag>
331     {    // map to managed tag
332 public:
333     typedef _Int_iterator_tag iterator_category;
334     };
335 #endif /* _M_CEE_SAFE */
336
337 //
338 // TEMPLATE CLASS iterator_traits
339 //
340 template<class _Iter_t>
341     value class iterator_traits
342     {    // get traits from iterator _Iter
343 public:
344     typedef typename _Map_iter_cat<
345         typename _Iter_t::iterator_category>::iterator_category
346         iterator_category;
347     typedef typename _Iter_t::value_type value_type;
348     typedef typename _Iter_t::difference_type difference_type;
349     typedef difference_type distance_type;    // retained
350     typedef typename _Iter_t::pointer pointer;
351     typedef typename _Iter_t::reference reference;
352     };
353
354 template<typename _Iter_t>
355     value class iterator_traits<_Iter_t^>
356     {    // get traits from managed pointer
357 public:
358     typedef typename _Iter_t::iterator_category iterator_category;
359     typedef typename _Iter_t::value_type value_type;
360     typedef typename _Iter_t::difference_type difference_type;
361     typedef difference_type distance_type;    // retained
362     typedef typename _Iter_t::pointer pointer;
363     typedef typename _Iter_t::reference reference;
364     };
365
366 #ifdef _M_CEE_SAFE
367 #else /* _M_CEE_SAFE */
368 template<class _Ty>
369     value class iterator_traits<_Ty *>
370     {    // get traits from pointer
371 public:
372     typedef random_access_iterator_tag iterator_category;
373     typedef _Ty value_type;
374     typedef std::ptrdiff_t difference_type;
375     typedef std::ptrdiff_t distance_type;    // retained
376     typedef _Ty *pointer;
377     typedef _Ty& reference;
378     };
379
380 template<class _Ty>
381     value class iterator_traits<const _Ty *>
382     {    // get traits from const pointer
383 public:
384     typedef random_access_iterator_tag iterator_category;
385     typedef _Ty value_type;
386     typedef std::ptrdiff_t difference_type;
387     typedef std::ptrdiff_t distance_type;    // retained
388     typedef const _Ty *pointer;
389     typedef const _Ty& reference;
390     };
391 #endif /* _M_CEE_SAFE */
392
393 //
394 // PARTIAL SPECIALIZATIONS OF iterator_traits
395 //
396 template<class _Ty>
397     value class iterator_traits<
398         _STLCLR Generic::IInputIterator<_Ty>>
399     {    // get traits from generic interface
400 public:
401     typedef input_iterator_tag iterator_category;
402     typedef _Ty value_type;
403     typedef int difference_type;
404     typedef int distance_type;    // retained
405     typedef typename _Ty% pointer;
406     typedef typename _Ty% reference;
407     };
408
409 template<class _Ty>
410     value class iterator_traits<
411         _STLCLR Generic::IOutputIterator<_Ty>>
412     {    // get traits from generic interface
413 public:
414     typedef output_iterator_tag iterator_category;
415     typedef _Ty value_type;
416     typedef int difference_type;
Lines 417 ... 699 are skipped.
700     typename _Diff_t> inline
701     void advance(_InIt_t% _Where, _Diff_t _Off)
702     {    // increment iterator by _Off, arbitrary iterators
703     _Iter_advance(_Where, _Off, _Iter_category(_Where));
704     }
705
706 //
707 // TEMPLATE FUNCTIONS distance and _Iter_distance
708 //
709 template<typename _InIt_t,
710     typename _Diff_t> inline
711     void _Iter_distance2(_InIt_t _First, _InIt_t _Last, _Diff_t% _Off,
712         input_iterator_tag)
713     {    // add to _Off distance between input iterators
714     for (; _First != _Last; ++_First)
715         ++_Off;
716     }
717
718 template<typename _RanIt_t,
719     typename _Diff_t> inline
720     void _Iter_distance2(_RanIt_t _First, _RanIt_t _Last, _Diff_t% _Off,
721         random_access_iterator_tag)
722     {    // add to _Off distance between random-access iterators
723     _Off += (_Diff_t)(_Last - _First);
724     }
725
726 template<typename _InIt_t> inline
727     int distance(_InIt_t _First, _InIt_t _Last)
728     {    // return distance between iterators
729     int _Off = 0;
730
731     _Iter_distance2(_First, _Last, _Off, _Iter_category(_First));
732     return (_Off);
733     }
734
735 template<typename _InIt_t,
736     typename _Diff_t> inline
737     void _Iter_distance(_InIt_t _First, _InIt_t _Last, _Diff_t% _Off)
738     {    // add to _Off distance between iterators
739     _Iter_distance2(_First, _Last, _Off, _Iter_category(_First));
740     }
741 }    // namespace cliext
742 #endif // _CLI_XUTILITY_
743
744 /*
745  * Copyright (c) 2004-2007 by Dinkumware, Ltd.  ALL RIGHTS RESERVED.
746  * Consult your license regarding permissions and restrictions.
747 V5.03:0009 */
748