OLD | NEW |
| (Empty) |
1 //+--------------------------------------------------------------------------- | |
2 // | |
3 // Copyright ( C ) Microsoft, 2002. | |
4 // | |
5 // File: smart_any_fwd.h | |
6 // | |
7 // Contents: automatic resource management | |
8 // | |
9 // Classes: auto_any, scoped_any and shared_any | |
10 // | |
11 // Functions: get | |
12 // reset | |
13 // release | |
14 // valid | |
15 // address | |
16 // | |
17 // Author: Eric Niebler ( ericne@microsoft.com ) | |
18 // | |
19 //---------------------------------------------------------------------------- | |
20 | |
21 #ifndef SMART_ANY_FWD | |
22 #define SMART_ANY_FWD | |
23 | |
24 #ifdef _MANAGED | |
25 #pragma warning( push ) | |
26 #pragma warning( disable : 4244 ) | |
27 #include <vcclr.h> | |
28 #pragma warning( pop ) | |
29 #endif | |
30 | |
31 // Check to see if partial template specialization is available | |
32 #if _MSC_VER >= 1310 | |
33 #define SMART_ANY_PTS | |
34 #endif | |
35 | |
36 // forward declare some invalid_value policy classes | |
37 struct null_t; | |
38 | |
39 template<typename T,T value = T(0)> | |
40 struct value_const; | |
41 | |
42 struct close_release_com; | |
43 | |
44 // | |
45 // TEMPLATE CLASS auto_any | |
46 // | |
47 template<typename T,class close_policy,class invalid_value = null_t,int unique =
0> | |
48 class auto_any; | |
49 | |
50 // return wrapped resource | |
51 template<typename T,class close_policy,class invalid_value,int unique> | |
52 T get( auto_any<T,close_policy,invalid_value,unique> const & t ); | |
53 | |
54 // return true if the auto_any contains a currently valid resource | |
55 template<typename T,class close_policy,class invalid_value,int unique> | |
56 bool valid( auto_any<T,close_policy,invalid_value,unique> const & t ); | |
57 | |
58 // return wrapped resource and give up ownership | |
59 template<typename T,class close_policy,class invalid_value,int unique> | |
60 T release( auto_any<T,close_policy,invalid_value, unique> & t ); | |
61 | |
62 // destroy designated object | |
63 template<typename T,class close_policy,class invalid_value,int unique> | |
64 void reset( auto_any<T,close_policy,invalid_value,unique> & t ); | |
65 | |
66 // destroy designated object and store new resource | |
67 template<typename T,class close_policy,class invalid_value,int unique,typename U
> | |
68 void reset( auto_any<T,close_policy,invalid_value,unique> & t, U newT ); | |
69 | |
70 // swap the contents of two shared_any objects | |
71 template<typename T,class close_policy,class invalid_value,int unique> | |
72 void swap( auto_any<T,close_policy,invalid_value,unique> & left, | |
73 auto_any<T,close_policy,invalid_value,unique> & right ); | |
74 | |
75 // return the address of the wrapped resource | |
76 // WARNING: this will assert if the value of the resource is | |
77 // anything other than invalid_value. | |
78 //template<typename T,class close_policy,class invalid_value,int unique> | |
79 //T* address( auto_any<T,close_policy,invalid_value,unique> & t ); | |
80 | |
81 // | |
82 // TEMPLATE CLASS shared_any | |
83 // | |
84 template<typename T,class close_policy,class invalid_value = null_t,int unique =
0> | |
85 class shared_any; | |
86 | |
87 // return wrapped resource | |
88 template<typename T,class close_policy,class invalid_value,int unique> | |
89 T get( shared_any<T,close_policy,invalid_value,unique> const & t ); | |
90 | |
91 // return true if the auto_any contains a currently valid resource | |
92 template<typename T,class close_policy,class invalid_value,int unique> | |
93 bool valid( shared_any<T,close_policy,invalid_value,unique> const & t ); | |
94 | |
95 // destroy designated object | |
96 template<typename T,class close_policy,class invalid_value,int unique> | |
97 void reset( shared_any<T,close_policy,invalid_value,unique> & t ); | |
98 | |
99 // destroy designated object and store new resource | |
100 template<typename T,class close_policy,class invalid_value,int unique,typename U
> | |
101 void reset( shared_any<T,close_policy,invalid_value,unique> & t, U newT ); | |
102 | |
103 // swap the contents of two shared_any objects | |
104 template<typename T,class close_policy,class invalid_value,int unique> | |
105 void swap( shared_any<T,close_policy,invalid_value,unique> & left, | |
106 shared_any<T,close_policy,invalid_value,unique> & right ); | |
107 | |
108 | |
109 // | |
110 // TEMPLATE CLASS scoped_any | |
111 // | |
112 template<typename T,class close_policy,class invalid_value = null_t,int unique =
0> | |
113 class scoped_any; | |
114 | |
115 // return wrapped resource | |
116 template<typename T,class close_policy,class invalid_value,int unique> | |
117 T get( scoped_any<T,close_policy,invalid_value,unique> const & t ); | |
118 | |
119 // return true if the auto_any contains a currently valid resource | |
120 template<typename T,class close_policy,class invalid_value,int unique> | |
121 bool valid( scoped_any<T,close_policy,invalid_value,unique> const & t ); | |
122 | |
123 // return wrapped resource and give up ownership | |
124 template<typename T,class close_policy,class invalid_value,int unique> | |
125 T release( scoped_any<T,close_policy,invalid_value, unique> & t ); | |
126 | |
127 // destroy designated object | |
128 template<typename T,class close_policy,class invalid_value,int unique> | |
129 void reset( scoped_any<T,close_policy,invalid_value,unique> & t ); | |
130 | |
131 // destroy designated object and store new resource | |
132 template<typename T,class close_policy,class invalid_value,int unique,typename U
> | |
133 void reset( scoped_any<T,close_policy,invalid_value,unique> & t, U newT ); | |
134 | |
135 // return the address of the wrapped resource | |
136 // WARNING: this will assert if the value of the resource is | |
137 // anything other than invalid_value. | |
138 //template<typename T,class close_policy,class invalid_value,int unique> | |
139 //T* address( scoped_any<T,close_policy,invalid_value,unique> & t ); | |
140 | |
141 // close policy for objects allocated with new | |
142 struct close_delete; | |
143 | |
144 namespace detail | |
145 { | |
146 typedef char (&yes)[1]; | |
147 typedef char (&no) [2]; | |
148 | |
149 struct dummy_struct | |
150 { | |
151 void dummy_method() {} | |
152 }; | |
153 | |
154 typedef void (dummy_struct::*safe_bool)(); | |
155 safe_bool const safe_true = &dummy_struct::dummy_method; | |
156 safe_bool const safe_false = 0; | |
157 | |
158 // Because of older compilers, we can't always use | |
159 // null_t when we would like to. | |
160 template<class invalid_value> | |
161 struct fixup_invalid_value | |
162 { | |
163 template<typename> struct rebind { typedef invalid_value type; }; | |
164 }; | |
165 | |
166 // for compile-time assertions | |
167 template<bool> | |
168 struct static_assert; | |
169 | |
170 template<> | |
171 struct static_assert<true> | |
172 { | |
173 static_assert() {} | |
174 }; | |
175 | |
176 template<typename T> | |
177 struct static_init | |
178 { | |
179 static T const value; | |
180 }; | |
181 | |
182 template<typename T> | |
183 T const static_init<T>::value = T(); | |
184 | |
185 template<bool> | |
186 struct null_helper // unmanaged | |
187 { | |
188 template<typename T> | |
189 struct inner | |
190 { | |
191 static T const get() | |
192 { | |
193 return static_init<T>::value; | |
194 } | |
195 }; | |
196 }; | |
197 | |
198 template<> | |
199 struct null_helper<true> // managed | |
200 { | |
201 template<typename T> | |
202 struct inner | |
203 { | |
204 static T const get() | |
205 { | |
206 return 0; | |
207 } | |
208 }; | |
209 }; | |
210 | |
211 typedef char (&yes_t)[1]; | |
212 typedef char (& no_t)[2]; | |
213 | |
214 template<bool> | |
215 struct select_helper | |
216 { | |
217 template<typename T,typename> | |
218 struct inner { typedef T type; }; | |
219 }; | |
220 | |
221 template<> | |
222 struct select_helper<false> | |
223 { | |
224 template<typename,typename U> | |
225 struct inner { typedef U type; }; | |
226 }; | |
227 | |
228 template<bool F,typename T,typename U> | |
229 struct select | |
230 { | |
231 typedef typename select_helper<F>::template inner<T,U>::type type; | |
232 }; | |
233 | |
234 | |
235 template< bool > | |
236 struct holder_helper | |
237 { | |
238 template<typename T> | |
239 struct inner | |
240 { | |
241 typedef T type; | |
242 }; | |
243 }; | |
244 | |
245 template< typename T > | |
246 struct remove_ref | |
247 { | |
248 typedef T type; | |
249 }; | |
250 | |
251 #ifdef SMART_ANY_PTS | |
252 template< typename T > | |
253 struct remove_ref<T&> | |
254 { | |
255 typedef T type; | |
256 }; | |
257 #endif | |
258 | |
259 template<typename T> | |
260 T* address_of( T & v ) | |
261 { | |
262 return reinterpret_cast<T*>( | |
263 &const_cast<char&>( | |
264 reinterpret_cast<char const volatile &>(v))); | |
265 } | |
266 | |
267 #ifndef _MANAGED | |
268 | |
269 template<typename T> | |
270 struct is_managed | |
271 { | |
272 static bool const value = false; | |
273 }; | |
274 | |
275 #else | |
276 | |
277 struct managed_convertible | |
278 { | |
279 managed_convertible( System::Object const volatile __gc* ); | |
280 managed_convertible( System::Enum const volatile __gc* ); | |
281 managed_convertible( System::ValueType const volatile __gc* ); | |
282 managed_convertible( System::Delegate const volatile __gc* ); | |
283 }; | |
284 | |
285 template<typename T> | |
286 struct is_managed | |
287 { | |
288 private: | |
289 static yes_t check( managed_convertible ); | |
290 static no_t __cdecl check( ... ); | |
291 static typename remove_ref<T>::type & make(); | |
292 public: | |
293 static bool const value = sizeof( yes_t ) == sizeof( check( make() ) ); | |
294 }; | |
295 | |
296 #ifdef SMART_ANY_PTS | |
297 template<typename T> | |
298 struct is_managed<T __gc&> | |
299 { | |
300 static bool const value = true; | |
301 }; | |
302 template<typename T> | |
303 struct is_managed<T __gc*> | |
304 { | |
305 static bool const value = true; | |
306 }; | |
307 template<typename T> | |
308 struct is_managed<T __gc*const> | |
309 { | |
310 static bool const value = is_managed<T __gc*>::value; | |
311 }; | |
312 template<typename T> | |
313 struct is_managed<T __gc*volatile> | |
314 { | |
315 static bool const value = is_managed<T __gc*>::value; | |
316 }; | |
317 template<typename T> | |
318 struct is_managed<T __gc*const volatile> | |
319 { | |
320 static bool const value = is_managed<T __gc*>::value; | |
321 }; | |
322 #endif | |
323 template<> | |
324 struct is_managed<System::Void __gc*> | |
325 { | |
326 static bool const value = true; | |
327 }; | |
328 template<> | |
329 struct is_managed<System::Void const __gc*> | |
330 { | |
331 static bool const value = true; | |
332 }; | |
333 template<> | |
334 struct is_managed<System::Void volatile __gc*> | |
335 { | |
336 static bool const value = true; | |
337 }; | |
338 template<> | |
339 struct is_managed<System::Void const volatile __gc*> | |
340 { | |
341 static bool const value = true; | |
342 }; | |
343 | |
344 template<> | |
345 struct holder_helper<true> | |
346 { | |
347 template<typename T> | |
348 struct inner | |
349 { | |
350 typedef gcroot<T> type; | |
351 }; | |
352 }; | |
353 #endif | |
354 | |
355 template<typename T> | |
356 struct holder | |
357 { | |
358 typedef typename holder_helper<is_managed<T>::value>::template inner<T>:
:type type; | |
359 }; | |
360 | |
361 template<typename T> | |
362 struct is_delete | |
363 { | |
364 static bool const value = false; | |
365 }; | |
366 | |
367 template<> | |
368 struct is_delete<close_delete> | |
369 { | |
370 static bool const value = true; | |
371 }; | |
372 | |
373 // dummy type, don't define | |
374 struct smart_any_cannot_dereference; | |
375 | |
376 // For use in implementing unary operator* | |
377 template<typename T> | |
378 struct deref | |
379 { | |
380 typedef smart_any_cannot_dereference type; // will cause a compile error
by default | |
381 }; | |
382 | |
383 #ifndef SMART_ANY_PTS | |
384 | |
385 // Old compiler needs extra help | |
386 template<> | |
387 struct fixup_invalid_value<null_t> | |
388 { | |
389 template<typename T> struct rebind { typedef value_const<T> type; }; | |
390 }; | |
391 | |
392 #else | |
393 | |
394 template<typename T,typename U> | |
395 struct same_type | |
396 { | |
397 static const bool value = false; | |
398 }; | |
399 | |
400 template<typename T> | |
401 struct same_type<T,T> | |
402 { | |
403 static const bool value = true; | |
404 }; | |
405 | |
406 // Handle reference types | |
407 template<typename T> | |
408 struct deref<T&> | |
409 { | |
410 typedef typename deref<T>::type type; | |
411 }; | |
412 | |
413 // Partially specialize for pointer types | |
414 template<typename T> | |
415 struct deref<T*> | |
416 { | |
417 typedef T& type; // The result of dereferencing a T* | |
418 }; | |
419 | |
420 // Partially specialize for pointer types | |
421 template<typename T> | |
422 struct deref<T*const> | |
423 { | |
424 typedef typename deref<T*>::type type; // The result of dereferencing a
T* | |
425 }; | |
426 | |
427 // Partially specialize for pointer types | |
428 template<typename T> | |
429 struct deref<T*volatile> | |
430 { | |
431 typedef typename deref<T*>::type type; // The result of dereferencing a
T* | |
432 }; | |
433 | |
434 // Partially specialize for pointer types | |
435 template<typename T> | |
436 struct deref<T*const volatile> | |
437 { | |
438 typedef typename deref<T*>::type type; // The result of dereferencing a
T* | |
439 }; | |
440 | |
441 // Fully specialize for void* | |
442 template<> | |
443 struct deref<void*> | |
444 { | |
445 typedef smart_any_cannot_dereference type; // cannot dereference a void* | |
446 }; | |
447 | |
448 // Fully specialize for void const* | |
449 template<> | |
450 struct deref<void const*> | |
451 { | |
452 typedef smart_any_cannot_dereference type; // cannot dereference a void* | |
453 }; | |
454 | |
455 // Fully specialize for void volatile* | |
456 template<> | |
457 struct deref<void volatile*> | |
458 { | |
459 typedef smart_any_cannot_dereference type; // cannot dereference a void* | |
460 }; | |
461 | |
462 // Fully specialize for void const volatile* | |
463 template<> | |
464 struct deref<void const volatile*> | |
465 { | |
466 typedef smart_any_cannot_dereference type; // cannot dereference a void* | |
467 }; | |
468 | |
469 #ifdef _MANAGED | |
470 // Handle reference types | |
471 template<typename T> | |
472 struct deref<T __gc&> | |
473 { | |
474 typedef typename deref<T>::type type; | |
475 }; | |
476 | |
477 // Partially specialize for pointer types | |
478 template<typename T> | |
479 struct deref<T __gc*> | |
480 { | |
481 typedef T __gc& type; // The result of dereferencing a T __gc* | |
482 }; | |
483 | |
484 // Partially specialize for pointer types | |
485 template<typename T> | |
486 struct deref<T __gc*const> | |
487 { | |
488 typedef typename deref<T __gc*>::type type; // The result of dereferenci
ng a T __gc* | |
489 }; | |
490 | |
491 // Partially specialize for pointer types | |
492 template<typename T> | |
493 struct deref<T __gc*volatile> | |
494 { | |
495 typedef typename deref<T __gc*>::type type; // The result of dereferenci
ng a T __gc* | |
496 }; | |
497 | |
498 // Partially specialize for pointer types | |
499 template<typename T> | |
500 struct deref<T __gc*const volatile> | |
501 { | |
502 typedef typename deref<T __gc*>::type type; // The result of dereferenci
ng a T __gc* | |
503 }; | |
504 | |
505 // Fully specialize for void* | |
506 template<> | |
507 struct deref<System::Void __gc*> | |
508 { | |
509 typedef smart_any_cannot_dereference type; // cannot dereference a Syste
m::Void __gc* | |
510 }; | |
511 | |
512 // Fully specialize for void const* | |
513 template<> | |
514 struct deref<System::Void const __gc*> | |
515 { | |
516 typedef smart_any_cannot_dereference type; // cannot dereference a Syste
m::Void __gc* | |
517 }; | |
518 | |
519 // Fully specialize for void volatile* | |
520 template<> | |
521 struct deref<System::Void volatile __gc*> | |
522 { | |
523 typedef smart_any_cannot_dereference type; // cannot dereference a Syste
m::Void __gc* | |
524 }; | |
525 | |
526 // Fully specialize for void const volatile* | |
527 template<> | |
528 struct deref<System::Void const volatile __gc*> | |
529 { | |
530 typedef smart_any_cannot_dereference type; // cannot dereference a Syste
m::Void __gc* | |
531 }; | |
532 #endif | |
533 | |
534 // The DECLARE_HANDLE macro in winnt.h defines a handle to be a pointer | |
535 // to a struct containing one member named "unused" of type int. We can | |
536 // use that information to make auto_any safer by disallowing actions like | |
537 // dereferencing a handle or calling delete on a handle. | |
538 template<typename T> | |
539 struct has_unused | |
540 { | |
541 private: | |
542 template<class U,int U::*> struct wrap_t; | |
543 template<typename U> static yes_t check( wrap_t<U,&U::unused>* ); | |
544 template<typename U> static no_t __cdecl check( ... ); | |
545 public: | |
546 static bool const value = ( sizeof(check<T>(0)) == sizeof(yes_t) ); | |
547 }; | |
548 | |
549 template<typename T> | |
550 struct is_handle_helper | |
551 { | |
552 static bool const value = ( sizeof(T)==sizeof(int) && has_unused<T>::val
ue ); | |
553 }; | |
554 | |
555 #ifdef _MANAGED | |
556 template<typename T> | |
557 struct is_handle_helper<T __gc&> | |
558 { | |
559 static bool const value = false; | |
560 }; | |
561 #endif | |
562 | |
563 template<> | |
564 struct is_handle_helper<smart_any_cannot_dereference> | |
565 { | |
566 static bool const value = false; | |
567 }; | |
568 | |
569 // used to see whether a given type T is a handle type or not. | |
570 template<typename T> | |
571 struct is_handle | |
572 { | |
573 private: | |
574 typedef typename remove_ref<typename deref<T>::type>::type deref_t; | |
575 public: | |
576 static bool const value = | |
577 ( same_type<T,void*>::value || is_handle_helper<deref_t>::value ); | |
578 }; | |
579 #endif | |
580 | |
581 template<typename T,class close_policy> | |
582 struct safe_types | |
583 { | |
584 typedef T pointer_type; | |
585 typedef typename deref<T>::type reference_type; | |
586 | |
587 static pointer_type to_pointer( T t ) | |
588 { | |
589 return t; | |
590 } | |
591 static reference_type to_reference( T t ) | |
592 { | |
593 return *t; | |
594 } | |
595 }; | |
596 | |
597 #ifdef SMART_ANY_PTS | |
598 template<typename T> | |
599 class no_addref_release : public T | |
600 { | |
601 unsigned long __stdcall AddRef(); | |
602 unsigned long __stdcall Release(); | |
603 }; | |
604 | |
605 // shouldn't be able to call AddRef or Release | |
606 // through a smart COM wrapper | |
607 template<typename T> | |
608 struct safe_types<T*,close_release_com> | |
609 { | |
610 typedef no_addref_release<T>* pointer_type; | |
611 typedef no_addref_release<T>& reference_type; | |
612 | |
613 static pointer_type to_pointer( T* t ) | |
614 { | |
615 return static_cast<pointer_type>( t ); | |
616 } | |
617 static reference_type to_reference( T* t ) | |
618 { | |
619 return *static_cast<pointer_type>( t ); | |
620 } | |
621 }; | |
622 #endif | |
623 } | |
624 | |
625 // a generic close policy that uses a ptr to a function | |
626 template<typename Fn, Fn Pfn> | |
627 struct close_fun | |
628 { | |
629 template<typename T> | |
630 static void close( T t ) | |
631 { | |
632 Pfn( t ); | |
633 } | |
634 }; | |
635 | |
636 // free an object allocated with new by calling delete | |
637 struct close_delete | |
638 { | |
639 template<typename T> | |
640 static void close( T * p ) | |
641 { | |
642 // This will fail only if T is an incomplete type. | |
643 static detail::static_assert<0 != sizeof( T )> const cannot_delete_an_in
complete_type; | |
644 | |
645 #ifdef SMART_ANY_PTS | |
646 // This checks to make sure we're not calling delete on a HANDLE | |
647 static detail::static_assert<!detail::is_handle<T*>::value> const cannot
_delete_a_handle; | |
648 #endif | |
649 | |
650 delete p; | |
651 } | |
652 | |
653 #ifdef _MANAGED | |
654 template<typename T> | |
655 static void close( gcroot<T __gc*> const & p ) | |
656 { | |
657 delete static_cast<T __gc*>( p ); | |
658 } | |
659 #endif | |
660 }; | |
661 | |
662 // free an array allocated with new[] by calling delete[] | |
663 struct close_delete_array | |
664 { | |
665 template<typename T> | |
666 static void close( T * p ) | |
667 { | |
668 // This will fail only if T is an incomplete type. | |
669 static detail::static_assert<0 != sizeof( T )> const cannot_delete_an_in
complete_type; | |
670 | |
671 #ifdef SMART_ANY_PTS | |
672 // This checks to make sure we're not calling delete on a HANDLE | |
673 static detail::static_assert<!detail::is_handle<T*>::value> const cannot
_delete_a_handle; | |
674 #endif | |
675 | |
676 delete [] p; | |
677 } | |
678 | |
679 //#ifdef _MANAGED | |
680 // This is broken because of compiler bugs | |
681 //template<typename T> | |
682 //static void close( gcroot<T __gc* __gc[]> const & p ) | |
683 //{ | |
684 // delete [] static_cast<T __gc* __gc[]>( p ); | |
685 //} | |
686 //#endif | |
687 }; | |
688 | |
689 // for releasing a COM object | |
690 struct close_release_com | |
691 { | |
692 template<typename T> | |
693 static void close( T p ) | |
694 { | |
695 p->Release(); | |
696 } | |
697 }; | |
698 | |
699 // for releasing a __gc IDisposable object | |
700 struct close_dispose | |
701 { | |
702 template<typename T> | |
703 static void close( T p ) | |
704 { | |
705 p->Dispose(); | |
706 } | |
707 }; | |
708 | |
709 // some generic invalid_value policies | |
710 | |
711 struct null_t | |
712 { | |
713 template<typename T> | |
714 operator T const() const | |
715 { | |
716 return detail::null_helper<detail::is_managed<T>::value>::template inner
<T>::get(); | |
717 } | |
718 }; | |
719 | |
720 template<typename T,T value> | |
721 struct value_const | |
722 { | |
723 operator T const() const | |
724 { | |
725 return value; | |
726 } | |
727 }; | |
728 | |
729 template<typename T,T const* value_ptr> | |
730 struct value_const_ptr | |
731 { | |
732 operator T const&() const | |
733 { | |
734 return *value_ptr; | |
735 } | |
736 }; | |
737 | |
738 #ifdef SMART_ANY_PTS | |
739 template<typename T, T const& value> | |
740 struct value_ref | |
741 { | |
742 operator T const&() const | |
743 { | |
744 return value; | |
745 } | |
746 }; | |
747 #endif | |
748 | |
749 #endif // SMART_ANY_FWD | |
750 | |
751 | |
752 // | |
753 // Define some other useful close polcies | |
754 // | |
755 | |
756 #if defined(_INC_STDLIB) | defined(_INC_MALLOC) | |
757 typedef void (__cdecl *pfn_free_t)( void* ); | |
758 typedef close_fun<pfn_free_t,static_cast<pfn_free_t>(&free)> clos
e_free; | |
759 #endif | |
760 | |
761 #if defined(_INC_STDIO) & !defined(SMART_CLOSE_FILE_PTR) | |
762 # define SMART_CLOSE_FILE_PTR | |
763 // don't close a FILE* if it is stdin, stdout or stderr | |
764 struct close_file_ptr | |
765 { | |
766 static void close( FILE * pfile ) | |
767 { | |
768 if( pfile != stdin && pfile != stdout && pfile != stderr ) | |
769 { | |
770 fclose( pfile ); | |
771 } | |
772 } | |
773 }; | |
774 #endif | |
775 | |
776 #ifdef _WINDOWS_ | |
777 | |
778 # ifndef SMART_VIRTUAL_FREE | |
779 # define SMART_VIRTUAL_FREE | |
780 // free memory allocated with VirtualAlloc | |
781 struct close_virtual_free | |
782 { | |
783 static void close( void * p ) | |
784 { | |
785 ::VirtualFree( p, 0, MEM_RELEASE ); | |
786 } | |
787 }; | |
788 # endif | |
789 | |
790 typedef close_fun<BOOL (__stdcall *)( HANDLE ),CloseHandle> clos
e_handle; | |
791 typedef close_fun<BOOL (__stdcall *)( HANDLE ),FindClose> clos
e_find; | |
792 typedef close_fun<BOOL (__stdcall *)( HANDLE ),FindCloseChangeNotification> cl
ose_find_change_notification; | |
793 typedef close_fun<BOOL (__stdcall *)( HINSTANCE ),FreeLibrary> clos
e_library; | |
794 typedef close_fun<LONG (__stdcall *)( HKEY ),RegCloseKey> clos
e_regkey; | |
795 typedef close_fun<BOOL (__stdcall *)( LPCVOID ),UnmapViewOfFile> clos
e_file_view; | |
796 typedef close_fun<BOOL (__stdcall *)( HICON ),DestroyIcon> clos
e_hicon; | |
797 typedef close_fun<BOOL (__stdcall *)( HGDIOBJ ),DeleteObject> clos
e_hgdiobj; | |
798 typedef close_fun<BOOL (__stdcall *)( HACCEL ),DestroyAcceleratorTable> clos
e_haccel; | |
799 typedef close_fun<BOOL (__stdcall *)( HDC ),DeleteDC> clos
e_hdc; | |
800 typedef close_fun<BOOL (__stdcall *)( HMENU ),DestroyMenu> clos
e_hmenu; | |
801 typedef close_fun<BOOL (__stdcall *)( HCURSOR ),DestroyCursor> clos
e_hcursor; | |
802 typedef close_fun<BOOL (__stdcall *)( HWND ),DestroyWindow> clos
e_window; | |
803 typedef close_fun<BOOL (__stdcall *)( HANDLE ),HeapDestroy> clos
e_heap_destroy; | |
804 typedef close_fun<HLOCAL (__stdcall *)( HLOCAL ),LocalFree> clos
e_local_free; | |
805 typedef close_fun<BOOL (__stdcall *)( HDESK ),CloseDesktop> clos
e_hdesk; | |
806 typedef close_fun<BOOL (__stdcall *)( HHOOK ),UnhookWindowsHookEx> clos
e_hhook; | |
807 typedef close_fun<BOOL (__stdcall *)( HWINSTA ),CloseWindowStation> clos
e_hwinsta; | |
808 typedef close_fun<BOOL (__stdcall *)( HANDLE ),DeregisterEventSource> clos
e_event_source; | |
809 typedef close_fun<HGLOBAL (__stdcall *)( HGLOBAL ),GlobalFree> clos
e_global_free; | |
810 | |
811 typedef value_const<HANDLE,INVALID_HANDLE_VALUE> inva
lid_handle_t; | |
812 #endif | |
813 | |
814 #ifdef _OLEAUTO_H_ | |
815 typedef close_fun<void (__stdcall *)(BSTR),SysFreeString> clos
e_bstr; | |
816 #endif | |
817 | |
818 #ifdef __MSGQUEUE_H__ | |
819 typedef close_fun<BOOL (__stdcall *)(HANDLE),CloseMsgQueue> clos
e_msg_queue; | |
820 #endif | |
821 | |
822 #if defined(_WININET_) | defined(_DUBINET_) | |
823 typedef close_fun<BOOL (__stdcall *)(HINTERNET),InternetCloseHandle> clos
e_hinternet; | |
824 #endif | |
825 | |
826 #ifdef _RAS_H_ | |
827 typedef close_fun<DWORD (__stdcall *)( HRASCONN ),RasHangUp> clos
e_hrasconn; | |
828 #endif | |
829 | |
830 #if defined(__RPCDCE_H__) & !defined(SMART_ANY_RPC) | |
831 # define SMART_ANY_RPC | |
832 // for releaseing an rpc binding | |
833 struct close_rpc_binding | |
834 { | |
835 static void close( RPC_BINDING_HANDLE & h ) | |
836 { | |
837 ::RpcBindingFree( &h ); | |
838 } | |
839 }; | |
840 // for releaseing an rpc binding vector | |
841 struct close_rpc_vector | |
842 { | |
843 static void close( RPC_BINDING_VECTOR __RPC_FAR * & p ) | |
844 { | |
845 ::RpcBindingVectorFree( &p ); | |
846 } | |
847 }; | |
848 // for releasing a RPC string | |
849 struct close_rpc_string | |
850 { | |
851 static void close( unsigned char __RPC_FAR * & p ) | |
852 { | |
853 ::RpcStringFreeA(&p); | |
854 } | |
855 static void close( unsigned short __RPC_FAR * & p ) | |
856 { | |
857 ::RpcStringFreeW(&p); | |
858 } | |
859 }; | |
860 #endif | |
861 | |
862 #ifdef _WINSVC_ | |
863 typedef close_fun<BOOL (__stdcall *)( SC_HANDLE ),CloseServiceHandle> clos
e_service; | |
864 typedef close_fun<BOOL (__stdcall *)( SC_LOCK ),UnlockServiceDatabase> unlo
ck_service; | |
865 #endif | |
866 | |
867 #ifdef _WINSOCKAPI_ | |
868 typedef int (__stdcall *pfn_closock_t)( SOCKET ); | |
869 typedef close_fun<pfn_closock_t,static_cast<pfn_closock_t>(&closesocket)> clos
e_socket; | |
870 typedef value_const<SOCKET,INVALID_SOCKET> inva
lid_socket_t; | |
871 #endif | |
872 | |
873 #ifdef _OBJBASE_H_ | |
874 // For use when releasing memory allocated with CoTaskMemAlloc | |
875 typedef close_fun<void (__stdcall*)( LPVOID ),CoTaskMemFree> clos
e_co_task_free; | |
876 #endif | |
877 | |
878 | |
879 // | |
880 // Below are useful smart typedefs for some common Windows/CRT resource types. | |
881 // | |
882 | |
883 #undef DECLARE_SMART_ANY_TYPEDEFS_STDIO | |
884 #undef DECLARE_SMART_ANY_TYPEDEFS_WINDOWS | |
885 #undef DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO | |
886 #undef DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE | |
887 #undef DECLARE_SMART_ANY_TYPEDEFS_WININET | |
888 #undef DECLARE_SMART_ANY_TYPEDEFS_RAS | |
889 #undef DECLARE_SMART_ANY_TYPEDEFS_RPCDCE | |
890 #undef DECLARE_SMART_ANY_TYPEDEFS_WINSVC | |
891 #undef DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI | |
892 #undef DECLARE_SMART_ANY_TYPEDEFS_OBJBASE | |
893 | |
894 #define DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix) | |
895 #define DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix) | |
896 #define DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix) | |
897 #define DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix) | |
898 #define DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix) | |
899 #define DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix) | |
900 #define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix) | |
901 #define DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix) | |
902 #define DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix) | |
903 #define DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix) | |
904 | |
905 #ifdef _INC_STDIO | |
906 # undef DECLARE_SMART_ANY_TYPEDEFS_STDIO | |
907 # define DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix)
\ | |
908 typedef prefix ## _any<FILE*,close_file_ptr>
prefix ## _file_ptr; | |
909 #endif | |
910 | |
911 #ifdef _WINDOWS_ | |
912 # undef DECLARE_SMART_ANY_TYPEDEFS_WINDOWS | |
913 # define DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix)
\ | |
914 typedef prefix ## _any<HKEY,close_regkey>
prefix ## _hkey; \ | |
915 typedef prefix ## _any<HANDLE,close_find,invalid_handle_t>
prefix ## _hfind; \ | |
916 typedef prefix ## _any<HANDLE,close_find_change_notification,invalid_handle_t>
prefix ## _hfind_change_notification; \ | |
917 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t>
prefix ## _hfile; \ | |
918 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,1>
prefix ## _communications_device; \ | |
919 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,2>
prefix ## _console_input; \ | |
920 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,3>
prefix ## _console_input_buffer; \ | |
921 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,4>
prefix ## _console_output; \ | |
922 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,5>
prefix ## _mailslot; \ | |
923 typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,6>
prefix ## _pipe; \ | |
924 typedef prefix ## _any<HANDLE,close_handle>
prefix ## _handle; \ | |
925 typedef prefix ## _any<HANDLE,close_handle,null_t,1>
prefix ## _access_token; \ | |
926 typedef prefix ## _any<HANDLE,close_handle,null_t,2>
prefix ## _event; \ | |
927 typedef prefix ## _any<HANDLE,close_handle,null_t,3>
prefix ## _file_mapping; \ | |
928 typedef prefix ## _any<HANDLE,close_handle,null_t,4>
prefix ## _job; \ | |
929 typedef prefix ## _any<HANDLE,close_handle,null_t,5>
prefix ## _mutex; \ | |
930 typedef prefix ## _any<HANDLE,close_handle,null_t,6>
prefix ## _process; \ | |
931 typedef prefix ## _any<HANDLE,close_handle,null_t,7>
prefix ## _semaphore; \ | |
932 typedef prefix ## _any<HANDLE,close_handle,null_t,8>
prefix ## _thread; \ | |
933 typedef prefix ## _any<HANDLE,close_handle,null_t,9>
prefix ## _timer; \ | |
934 typedef prefix ## _any<HANDLE,close_handle,null_t,10>
prefix ## _completion_port; \ | |
935 typedef prefix ## _any<HDC,close_hdc>
prefix ## _hdc; \ | |
936 typedef prefix ## _any<HICON,close_hicon>
prefix ## _hicon; \ | |
937 typedef prefix ## _any<HMENU,close_hmenu>
prefix ## _hmenu; \ | |
938 typedef prefix ## _any<HCURSOR,close_hcursor>
prefix ## _hcursor; \ | |
939 typedef prefix ## _any<HPEN,close_hgdiobj,null_t,1>
prefix ## _hpen; \ | |
940 typedef prefix ## _any<HRGN,close_hgdiobj,null_t,2>
prefix ## _hrgn; \ | |
941 typedef prefix ## _any<HFONT,close_hgdiobj,null_t,3>
prefix ## _hfont; \ | |
942 typedef prefix ## _any<HBRUSH,close_hgdiobj,null_t,4>
prefix ## _hbrush; \ | |
943 typedef prefix ## _any<HBITMAP,close_hgdiobj,null_t,5>
prefix ## _hbitmap; \ | |
944 typedef prefix ## _any<HPALETTE,close_hgdiobj,null_t,6>
prefix ## _hpalette; \ | |
945 typedef prefix ## _any<HACCEL,close_haccel>
prefix ## _haccel; \ | |
946 typedef prefix ## _any<HWND,close_window>
prefix ## _window; \ | |
947 typedef prefix ## _any<HINSTANCE,close_library>
prefix ## _library; \ | |
948 typedef prefix ## _any<LPVOID,close_file_view>
prefix ## _file_view; \ | |
949 typedef prefix ## _any<LPVOID,close_virtual_free>
prefix ## _virtual_ptr; \ | |
950 typedef prefix ## _any<HANDLE,close_heap_destroy>
prefix ## _heap; \ | |
951 typedef prefix ## _any<HLOCAL,close_local_free>
prefix ## _hlocal; \ | |
952 typedef prefix ## _any<HDESK,close_hdesk>
prefix ## _hdesk; \ | |
953 typedef prefix ## _any<HHOOK,close_hhook>
prefix ## _hhook; \ | |
954 typedef prefix ## _any<HWINSTA,close_hwinsta>
prefix ## _hwinsta; \ | |
955 typedef prefix ## _any<HANDLE,close_event_source>
prefix ## _event_source; \ | |
956 typedef prefix ## _any<HGLOBAL,close_global_free>
prefix ## _hglobal; | |
957 #endif | |
958 | |
959 // | |
960 // Define some other useful typedefs | |
961 // | |
962 | |
963 #ifdef _OLEAUTO_H_ | |
964 # undef DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO | |
965 # define DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix)
\ | |
966 typedef prefix ## _any<BSTR,close_bstr>
prefix ## _bstr; | |
967 #endif | |
968 | |
969 #ifdef __MSGQUEUE_H__ | |
970 # undef DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE | |
971 # define DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix)
\ | |
972 typedef prefix ## _any<HANDLE,close_msg_queue>
prefix ## _msg_queue; | |
973 #endif | |
974 | |
975 #if defined(_WININET_) | defined(_DUBINET_) | |
976 # undef DECLARE_SMART_ANY_TYPEDEFS_WININET | |
977 # define DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix)
\ | |
978 typedef prefix ## _any<HINTERNET,close_hinternet>
prefix ## _hinternet; | |
979 #endif | |
980 | |
981 #ifdef _RAS_H_ | |
982 # undef DECLARE_SMART_ANY_TYPEDEFS_RAS | |
983 # define DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix)
\ | |
984 typedef prefix ## _any<HRASCONN,close_hrasconn>
prefix ## _hrasconn; | |
985 #endif | |
986 | |
987 #ifdef __RPCDCE_H__ | |
988 # undef DECLARE_SMART_ANY_TYPEDEFS_RPCDCE | |
989 # ifdef UNICODE | |
990 # define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix)
\ | |
991 typedef prefix ## _any<RPC_BINDING_HANDLE,close_rpc_binding>
prefix ## _rpc_binding; \ | |
992 typedef prefix ## _any<RPC_BINDING_VECTOR __RPC_FAR*,close_rpc_vector>
prefix ## _rpc_binding_vector; \ | |
993 typedef prefix ## _any<unsigned char __RPC_FAR*,close_rpc_string>
prefix ## _rpc_string_A; \ | |
994 typedef prefix ## _any<unsigned short __RPC_FAR*,close_rpc_string>
prefix ## _rpc_string_W; \ | |
995 typedef prefix ## _rpc_string_W
prefix ## _rpc_string; | |
996 # else | |
997 # define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix)
\ | |
998 typedef prefix ## _any<RPC_BINDING_HANDLE,close_rpc_binding>
prefix ## _rpc_binding; \ | |
999 typedef prefix ## _any<RPC_BINDING_VECTOR __RPC_FAR*,close_rpc_vector>
prefix ## _rpc_binding_vector; \ | |
1000 typedef prefix ## _any<unsigned char __RPC_FAR*,close_rpc_string>
prefix ## _rpc_string_A; \ | |
1001 typedef prefix ## _any<unsigned short __RPC_FAR*,close_rpc_string>
prefix ## _rpc_string_W; \ | |
1002 typedef prefix ## _rpc_string_A
prefix ## _rpc_string; | |
1003 # endif | |
1004 #endif | |
1005 | |
1006 #ifdef _WINSVC_ | |
1007 # undef DECLARE_SMART_ANY_TYPEDEFS_WINSVC | |
1008 # define DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix)
\ | |
1009 typedef prefix ## _any<SC_HANDLE,close_service>
prefix ## _service; \ | |
1010 typedef prefix ## _any<SC_LOCK,unlock_service>
prefix ## _service_lock; | |
1011 #endif | |
1012 | |
1013 #ifdef _WINSOCKAPI_ | |
1014 # undef DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI | |
1015 # define DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix)
\ | |
1016 typedef prefix ## _any<SOCKET,close_socket,invalid_socket_t>
prefix ## _socket; | |
1017 #endif | |
1018 | |
1019 #if defined(_OBJBASE_H_) & !defined(SMART_ANY_CO_INIT) | |
1020 # define SMART_ANY_CO_INIT | |
1021 inline HRESULT smart_co_init_helper( DWORD dwCoInit ) | |
1022 { | |
1023 (void) dwCoInit; | |
1024 # if (_WIN32_WINNT >= 0x0400 ) | defined(_WIN32_DCOM) | |
1025 return ::CoInitializeEx(0,dwCoInit); | |
1026 # else | |
1027 return ::CoInitialize(0); | |
1028 # endif | |
1029 } | |
1030 inline void smart_co_uninit_helper( HRESULT hr ) | |
1031 { | |
1032 if (SUCCEEDED(hr)) | |
1033 ::CoUninitialize(); | |
1034 } | |
1035 typedef close_fun<void(*)(HRESULT),smart_co_uninit_helper>
close_co; | |
1036 typedef value_const<HRESULT,CO_E_NOTINITIALIZED>
co_not_init; | |
1037 # undef DECLARE_SMART_ANY_TYPEDEFS_OBJBASE | |
1038 # define DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix)
\ | |
1039 typedef prefix ## _any<LPVOID,close_co_task_free>
prefix ## _co_task_ptr; | |
1040 #endif | |
1041 | |
1042 | |
1043 #define DECLARE_SMART_ANY_TYPEDEFS(prefix)
\ | |
1044 DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix)
\ | |
1045 DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix)
\ | |
1046 DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix)
\ | |
1047 DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix)
\ | |
1048 DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix)
\ | |
1049 DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix)
\ | |
1050 DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix)
\ | |
1051 DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix)
\ | |
1052 DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix)
\ | |
1053 DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix) | |
OLD | NEW |