blob: d9552a99b87d57479eb48794256f3ac69b858531 [file] [log] [blame]
//+---------------------------------------------------------------------------
//
// Copyright ( C ) Microsoft, 2002.
//
// File: smart_any_fwd.h
//
// Contents: automatic resource management
//
// Classes: auto_any, scoped_any and shared_any
//
// Functions: get
// reset
// release
// valid
// address
//
// Author: Eric Niebler ( ericne@microsoft.com )
//
//----------------------------------------------------------------------------
#ifndef SMART_ANY_FWD
#define SMART_ANY_FWD
#ifdef _MANAGED
#pragma warning( push )
#pragma warning( disable : 4244 )
#include <vcclr.h>
#pragma warning( pop )
#endif
// Check to see if partial template specialization is available
#if _MSC_VER >= 1310
#define SMART_ANY_PTS
#endif
// forward declare some invalid_value policy classes
struct null_t;
template<typename T,T value = T(0)>
struct value_const;
struct close_release_com;
//
// TEMPLATE CLASS auto_any
//
template<typename T,class close_policy,class invalid_value = null_t,int unique = 0>
class auto_any;
// return wrapped resource
template<typename T,class close_policy,class invalid_value,int unique>
T get( auto_any<T,close_policy,invalid_value,unique> const & t );
// return true if the auto_any contains a currently valid resource
template<typename T,class close_policy,class invalid_value,int unique>
bool valid( auto_any<T,close_policy,invalid_value,unique> const & t );
// return wrapped resource and give up ownership
template<typename T,class close_policy,class invalid_value,int unique>
T release( auto_any<T,close_policy,invalid_value, unique> & t );
// destroy designated object
template<typename T,class close_policy,class invalid_value,int unique>
void reset( auto_any<T,close_policy,invalid_value,unique> & t );
// destroy designated object and store new resource
template<typename T,class close_policy,class invalid_value,int unique,typename U>
void reset( auto_any<T,close_policy,invalid_value,unique> & t, U newT );
// swap the contents of two shared_any objects
template<typename T,class close_policy,class invalid_value,int unique>
void swap( auto_any<T,close_policy,invalid_value,unique> & left,
auto_any<T,close_policy,invalid_value,unique> & right );
// return the address of the wrapped resource
// WARNING: this will assert if the value of the resource is
// anything other than invalid_value.
//template<typename T,class close_policy,class invalid_value,int unique>
//T* address( auto_any<T,close_policy,invalid_value,unique> & t );
//
// TEMPLATE CLASS shared_any
//
template<typename T,class close_policy,class invalid_value = null_t,int unique = 0>
class shared_any;
// return wrapped resource
template<typename T,class close_policy,class invalid_value,int unique>
T get( shared_any<T,close_policy,invalid_value,unique> const & t );
// return true if the auto_any contains a currently valid resource
template<typename T,class close_policy,class invalid_value,int unique>
bool valid( shared_any<T,close_policy,invalid_value,unique> const & t );
// destroy designated object
template<typename T,class close_policy,class invalid_value,int unique>
void reset( shared_any<T,close_policy,invalid_value,unique> & t );
// destroy designated object and store new resource
template<typename T,class close_policy,class invalid_value,int unique,typename U>
void reset( shared_any<T,close_policy,invalid_value,unique> & t, U newT );
// swap the contents of two shared_any objects
template<typename T,class close_policy,class invalid_value,int unique>
void swap( shared_any<T,close_policy,invalid_value,unique> & left,
shared_any<T,close_policy,invalid_value,unique> & right );
//
// TEMPLATE CLASS scoped_any
//
template<typename T,class close_policy,class invalid_value = null_t,int unique = 0>
class scoped_any;
// return wrapped resource
template<typename T,class close_policy,class invalid_value,int unique>
T get( scoped_any<T,close_policy,invalid_value,unique> const & t );
// return true if the auto_any contains a currently valid resource
template<typename T,class close_policy,class invalid_value,int unique>
bool valid( scoped_any<T,close_policy,invalid_value,unique> const & t );
// return wrapped resource and give up ownership
template<typename T,class close_policy,class invalid_value,int unique>
T release( scoped_any<T,close_policy,invalid_value, unique> & t );
// destroy designated object
template<typename T,class close_policy,class invalid_value,int unique>
void reset( scoped_any<T,close_policy,invalid_value,unique> & t );
// destroy designated object and store new resource
template<typename T,class close_policy,class invalid_value,int unique,typename U>
void reset( scoped_any<T,close_policy,invalid_value,unique> & t, U newT );
// return the address of the wrapped resource
// WARNING: this will assert if the value of the resource is
// anything other than invalid_value.
//template<typename T,class close_policy,class invalid_value,int unique>
//T* address( scoped_any<T,close_policy,invalid_value,unique> & t );
// close policy for objects allocated with new
struct close_delete;
namespace detail
{
typedef char (&yes)[1];
typedef char (&no) [2];
struct dummy_struct
{
void dummy_method() {}
};
typedef void (dummy_struct::*safe_bool)();
safe_bool const safe_true = &dummy_struct::dummy_method;
safe_bool const safe_false = 0;
// Because of older compilers, we can't always use
// null_t when we would like to.
template<class invalid_value>
struct fixup_invalid_value
{
template<typename> struct rebind { typedef invalid_value type; };
};
// for compile-time assertions
template<bool>
struct static_assert;
template<>
struct static_assert<true>
{
static_assert() {}
};
template<typename T>
struct static_init
{
static T const value;
};
template<typename T>
T const static_init<T>::value = T();
template<bool>
struct null_helper // unmanaged
{
template<typename T>
struct inner
{
static T const get()
{
return static_init<T>::value;
}
};
};
template<>
struct null_helper<true> // managed
{
template<typename T>
struct inner
{
static T const get()
{
return 0;
}
};
};
typedef char (&yes_t)[1];
typedef char (& no_t)[2];
template<bool>
struct select_helper
{
template<typename T,typename>
struct inner { typedef T type; };
};
template<>
struct select_helper<false>
{
template<typename,typename U>
struct inner { typedef U type; };
};
template<bool F,typename T,typename U>
struct select
{
typedef typename select_helper<F>::template inner<T,U>::type type;
};
template< bool >
struct holder_helper
{
template<typename T>
struct inner
{
typedef T type;
};
};
template< typename T >
struct remove_ref
{
typedef T type;
};
#ifdef SMART_ANY_PTS
template< typename T >
struct remove_ref<T&>
{
typedef T type;
};
#endif
template<typename T>
T* address_of( T & v )
{
return reinterpret_cast<T*>(
&const_cast<char&>(
reinterpret_cast<char const volatile &>(v)));
}
#ifndef _MANAGED
template<typename T>
struct is_managed
{
static bool const value = false;
};
#else
struct managed_convertible
{
managed_convertible( System::Object const volatile __gc* );
managed_convertible( System::Enum const volatile __gc* );
managed_convertible( System::ValueType const volatile __gc* );
managed_convertible( System::Delegate const volatile __gc* );
};
template<typename T>
struct is_managed
{
private:
static yes_t check( managed_convertible );
static no_t __cdecl check( ... );
static typename remove_ref<T>::type & make();
public:
static bool const value = sizeof( yes_t ) == sizeof( check( make() ) );
};
#ifdef SMART_ANY_PTS
template<typename T>
struct is_managed<T __gc&>
{
static bool const value = true;
};
template<typename T>
struct is_managed<T __gc*>
{
static bool const value = true;
};
template<typename T>
struct is_managed<T __gc*const>
{
static bool const value = is_managed<T __gc*>::value;
};
template<typename T>
struct is_managed<T __gc*volatile>
{
static bool const value = is_managed<T __gc*>::value;
};
template<typename T>
struct is_managed<T __gc*const volatile>
{
static bool const value = is_managed<T __gc*>::value;
};
#endif
template<>
struct is_managed<System::Void __gc*>
{
static bool const value = true;
};
template<>
struct is_managed<System::Void const __gc*>
{
static bool const value = true;
};
template<>
struct is_managed<System::Void volatile __gc*>
{
static bool const value = true;
};
template<>
struct is_managed<System::Void const volatile __gc*>
{
static bool const value = true;
};
template<>
struct holder_helper<true>
{
template<typename T>
struct inner
{
typedef gcroot<T> type;
};
};
#endif
template<typename T>
struct holder
{
typedef typename holder_helper<is_managed<T>::value>::template inner<T>::type type;
};
template<typename T>
struct is_delete
{
static bool const value = false;
};
template<>
struct is_delete<close_delete>
{
static bool const value = true;
};
// dummy type, don't define
struct smart_any_cannot_dereference;
// For use in implementing unary operator*
template<typename T>
struct deref
{
typedef smart_any_cannot_dereference type; // will cause a compile error by default
};
#ifndef SMART_ANY_PTS
// Old compiler needs extra help
template<>
struct fixup_invalid_value<null_t>
{
template<typename T> struct rebind { typedef value_const<T> type; };
};
#else
template<typename T,typename U>
struct same_type
{
static const bool value = false;
};
template<typename T>
struct same_type<T,T>
{
static const bool value = true;
};
// Handle reference types
template<typename T>
struct deref<T&>
{
typedef typename deref<T>::type type;
};
// Partially specialize for pointer types
template<typename T>
struct deref<T*>
{
typedef T& type; // The result of dereferencing a T*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T*const>
{
typedef typename deref<T*>::type type; // The result of dereferencing a T*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T*volatile>
{
typedef typename deref<T*>::type type; // The result of dereferencing a T*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T*const volatile>
{
typedef typename deref<T*>::type type; // The result of dereferencing a T*
};
// Fully specialize for void*
template<>
struct deref<void*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a void*
};
// Fully specialize for void const*
template<>
struct deref<void const*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a void*
};
// Fully specialize for void volatile*
template<>
struct deref<void volatile*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a void*
};
// Fully specialize for void const volatile*
template<>
struct deref<void const volatile*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a void*
};
#ifdef _MANAGED
// Handle reference types
template<typename T>
struct deref<T __gc&>
{
typedef typename deref<T>::type type;
};
// Partially specialize for pointer types
template<typename T>
struct deref<T __gc*>
{
typedef T __gc& type; // The result of dereferencing a T __gc*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T __gc*const>
{
typedef typename deref<T __gc*>::type type; // The result of dereferencing a T __gc*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T __gc*volatile>
{
typedef typename deref<T __gc*>::type type; // The result of dereferencing a T __gc*
};
// Partially specialize for pointer types
template<typename T>
struct deref<T __gc*const volatile>
{
typedef typename deref<T __gc*>::type type; // The result of dereferencing a T __gc*
};
// Fully specialize for void*
template<>
struct deref<System::Void __gc*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a System::Void __gc*
};
// Fully specialize for void const*
template<>
struct deref<System::Void const __gc*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a System::Void __gc*
};
// Fully specialize for void volatile*
template<>
struct deref<System::Void volatile __gc*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a System::Void __gc*
};
// Fully specialize for void const volatile*
template<>
struct deref<System::Void const volatile __gc*>
{
typedef smart_any_cannot_dereference type; // cannot dereference a System::Void __gc*
};
#endif
// The DECLARE_HANDLE macro in winnt.h defines a handle to be a pointer
// to a struct containing one member named "unused" of type int. We can
// use that information to make auto_any safer by disallowing actions like
// dereferencing a handle or calling delete on a handle.
template<typename T>
struct has_unused
{
private:
template<class U,int U::*> struct wrap_t;
template<typename U> static yes_t check( wrap_t<U,&U::unused>* );
template<typename U> static no_t __cdecl check( ... );
public:
static bool const value = ( sizeof(check<T>(0)) == sizeof(yes_t) );
};
template<typename T>
struct is_handle_helper
{
static bool const value = ( sizeof(T)==sizeof(int) && has_unused<T>::value );
};
#ifdef _MANAGED
template<typename T>
struct is_handle_helper<T __gc&>
{
static bool const value = false;
};
#endif
template<>
struct is_handle_helper<smart_any_cannot_dereference>
{
static bool const value = false;
};
// used to see whether a given type T is a handle type or not.
template<typename T>
struct is_handle
{
private:
typedef typename remove_ref<typename deref<T>::type>::type deref_t;
public:
static bool const value =
( same_type<T,void*>::value || is_handle_helper<deref_t>::value );
};
#endif
template<typename T,class close_policy>
struct safe_types
{
typedef T pointer_type;
typedef typename deref<T>::type reference_type;
static pointer_type to_pointer( T t )
{
return t;
}
static reference_type to_reference( T t )
{
return *t;
}
};
#ifdef SMART_ANY_PTS
template<typename T>
class no_addref_release : public T
{
unsigned long __stdcall AddRef();
unsigned long __stdcall Release();
};
// shouldn't be able to call AddRef or Release
// through a smart COM wrapper
template<typename T>
struct safe_types<T*,close_release_com>
{
typedef no_addref_release<T>* pointer_type;
typedef no_addref_release<T>& reference_type;
static pointer_type to_pointer( T* t )
{
return static_cast<pointer_type>( t );
}
static reference_type to_reference( T* t )
{
return *static_cast<pointer_type>( t );
}
};
#endif
}
// a generic close policy that uses a ptr to a function
template<typename Fn, Fn Pfn>
struct close_fun
{
template<typename T>
static void close( T t )
{
Pfn( t );
}
};
// free an object allocated with new by calling delete
struct close_delete
{
template<typename T>
static void close( T * p )
{
// This will fail only if T is an incomplete type.
static detail::static_assert<0 != sizeof( T )> const cannot_delete_an_incomplete_type;
#ifdef SMART_ANY_PTS
// This checks to make sure we're not calling delete on a HANDLE
static detail::static_assert<!detail::is_handle<T*>::value> const cannot_delete_a_handle;
#endif
delete p;
}
#ifdef _MANAGED
template<typename T>
static void close( gcroot<T __gc*> const & p )
{
delete static_cast<T __gc*>( p );
}
#endif
};
// free an array allocated with new[] by calling delete[]
struct close_delete_array
{
template<typename T>
static void close( T * p )
{
// This will fail only if T is an incomplete type.
static detail::static_assert<0 != sizeof( T )> const cannot_delete_an_incomplete_type;
#ifdef SMART_ANY_PTS
// This checks to make sure we're not calling delete on a HANDLE
static detail::static_assert<!detail::is_handle<T*>::value> const cannot_delete_a_handle;
#endif
delete [] p;
}
//#ifdef _MANAGED
// This is broken because of compiler bugs
//template<typename T>
//static void close( gcroot<T __gc* __gc[]> const & p )
//{
// delete [] static_cast<T __gc* __gc[]>( p );
//}
//#endif
};
// for releasing a COM object
struct close_release_com
{
template<typename T>
static void close( T p )
{
p->Release();
}
};
// for releasing a __gc IDisposable object
struct close_dispose
{
template<typename T>
static void close( T p )
{
p->Dispose();
}
};
// some generic invalid_value policies
struct null_t
{
template<typename T>
operator T const() const
{
return detail::null_helper<detail::is_managed<T>::value>::template inner<T>::get();
}
};
template<typename T,T value>
struct value_const
{
operator T const() const
{
return value;
}
};
template<typename T,T const* value_ptr>
struct value_const_ptr
{
operator T const&() const
{
return *value_ptr;
}
};
#ifdef SMART_ANY_PTS
template<typename T, T const& value>
struct value_ref
{
operator T const&() const
{
return value;
}
};
#endif
#endif // SMART_ANY_FWD
//
// Define some other useful close polcies
//
#if defined(_INC_STDLIB) | defined(_INC_MALLOC)
typedef void (__cdecl *pfn_free_t)( void* );
typedef close_fun<pfn_free_t,static_cast<pfn_free_t>(&free)> close_free;
#endif
#if defined(_INC_STDIO) & !defined(SMART_CLOSE_FILE_PTR)
# define SMART_CLOSE_FILE_PTR
// don't close a FILE* if it is stdin, stdout or stderr
struct close_file_ptr
{
static void close( FILE * pfile )
{
if( pfile != stdin && pfile != stdout && pfile != stderr )
{
fclose( pfile );
}
}
};
#endif
#ifdef _WINDOWS_
# ifndef SMART_VIRTUAL_FREE
# define SMART_VIRTUAL_FREE
// free memory allocated with VirtualAlloc
struct close_virtual_free
{
static void close( void * p )
{
::VirtualFree( p, 0, MEM_RELEASE );
}
};
# endif
typedef close_fun<BOOL (__stdcall *)( HANDLE ),CloseHandle> close_handle;
typedef close_fun<BOOL (__stdcall *)( HANDLE ),FindClose> close_find;
typedef close_fun<BOOL (__stdcall *)( HANDLE ),FindCloseChangeNotification> close_find_change_notification;
typedef close_fun<BOOL (__stdcall *)( HINSTANCE ),FreeLibrary> close_library;
typedef close_fun<LONG (__stdcall *)( HKEY ),RegCloseKey> close_regkey;
typedef close_fun<BOOL (__stdcall *)( LPCVOID ),UnmapViewOfFile> close_file_view;
typedef close_fun<BOOL (__stdcall *)( HICON ),DestroyIcon> close_hicon;
typedef close_fun<BOOL (__stdcall *)( HGDIOBJ ),DeleteObject> close_hgdiobj;
typedef close_fun<BOOL (__stdcall *)( HACCEL ),DestroyAcceleratorTable> close_haccel;
typedef close_fun<BOOL (__stdcall *)( HDC ),DeleteDC> close_hdc;
typedef close_fun<BOOL (__stdcall *)( HMENU ),DestroyMenu> close_hmenu;
typedef close_fun<BOOL (__stdcall *)( HCURSOR ),DestroyCursor> close_hcursor;
typedef close_fun<BOOL (__stdcall *)( HWND ),DestroyWindow> close_window;
typedef close_fun<BOOL (__stdcall *)( HANDLE ),HeapDestroy> close_heap_destroy;
typedef close_fun<HLOCAL (__stdcall *)( HLOCAL ),LocalFree> close_local_free;
typedef close_fun<BOOL (__stdcall *)( HDESK ),CloseDesktop> close_hdesk;
typedef close_fun<BOOL (__stdcall *)( HHOOK ),UnhookWindowsHookEx> close_hhook;
typedef close_fun<BOOL (__stdcall *)( HWINSTA ),CloseWindowStation> close_hwinsta;
typedef close_fun<BOOL (__stdcall *)( HANDLE ),DeregisterEventSource> close_event_source;
typedef close_fun<HGLOBAL (__stdcall *)( HGLOBAL ),GlobalFree> close_global_free;
typedef value_const<HANDLE,INVALID_HANDLE_VALUE> invalid_handle_t;
#endif
#ifdef _OLEAUTO_H_
typedef close_fun<void (__stdcall *)(BSTR),SysFreeString> close_bstr;
#endif
#ifdef __MSGQUEUE_H__
typedef close_fun<BOOL (__stdcall *)(HANDLE),CloseMsgQueue> close_msg_queue;
#endif
#if defined(_WININET_) | defined(_DUBINET_)
typedef close_fun<BOOL (__stdcall *)(HINTERNET),InternetCloseHandle> close_hinternet;
#endif
#ifdef _RAS_H_
typedef close_fun<DWORD (__stdcall *)( HRASCONN ),RasHangUp> close_hrasconn;
#endif
#if defined(__RPCDCE_H__) & !defined(SMART_ANY_RPC)
# define SMART_ANY_RPC
// for releaseing an rpc binding
struct close_rpc_binding
{
static void close( RPC_BINDING_HANDLE & h )
{
::RpcBindingFree( &h );
}
};
// for releaseing an rpc binding vector
struct close_rpc_vector
{
static void close( RPC_BINDING_VECTOR __RPC_FAR * & p )
{
::RpcBindingVectorFree( &p );
}
};
// for releasing a RPC string
struct close_rpc_string
{
static void close( unsigned char __RPC_FAR * & p )
{
::RpcStringFreeA(&p);
}
static void close( unsigned short __RPC_FAR * & p )
{
::RpcStringFreeW(&p);
}
};
#endif
#ifdef _WINSVC_
typedef close_fun<BOOL (__stdcall *)( SC_HANDLE ),CloseServiceHandle> close_service;
typedef close_fun<BOOL (__stdcall *)( SC_LOCK ),UnlockServiceDatabase> unlock_service;
#endif
#ifdef _WINSOCKAPI_
typedef int (__stdcall *pfn_closock_t)( SOCKET );
typedef close_fun<pfn_closock_t,static_cast<pfn_closock_t>(&closesocket)> close_socket;
typedef value_const<SOCKET,INVALID_SOCKET> invalid_socket_t;
#endif
#ifdef _OBJBASE_H_
// For use when releasing memory allocated with CoTaskMemAlloc
typedef close_fun<void (__stdcall*)( LPVOID ),CoTaskMemFree> close_co_task_free;
#endif
//
// Below are useful smart typedefs for some common Windows/CRT resource types.
//
#undef DECLARE_SMART_ANY_TYPEDEFS_STDIO
#undef DECLARE_SMART_ANY_TYPEDEFS_WINDOWS
#undef DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO
#undef DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE
#undef DECLARE_SMART_ANY_TYPEDEFS_WININET
#undef DECLARE_SMART_ANY_TYPEDEFS_RAS
#undef DECLARE_SMART_ANY_TYPEDEFS_RPCDCE
#undef DECLARE_SMART_ANY_TYPEDEFS_WINSVC
#undef DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI
#undef DECLARE_SMART_ANY_TYPEDEFS_OBJBASE
#define DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix)
#define DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix)
#ifdef _INC_STDIO
# undef DECLARE_SMART_ANY_TYPEDEFS_STDIO
# define DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix) \
typedef prefix ## _any<FILE*,close_file_ptr> prefix ## _file_ptr;
#endif
#ifdef _WINDOWS_
# undef DECLARE_SMART_ANY_TYPEDEFS_WINDOWS
# define DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix) \
typedef prefix ## _any<HKEY,close_regkey> prefix ## _hkey; \
typedef prefix ## _any<HANDLE,close_find,invalid_handle_t> prefix ## _hfind; \
typedef prefix ## _any<HANDLE,close_find_change_notification,invalid_handle_t> prefix ## _hfind_change_notification; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t> prefix ## _hfile; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,1> prefix ## _communications_device; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,2> prefix ## _console_input; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,3> prefix ## _console_input_buffer; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,4> prefix ## _console_output; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,5> prefix ## _mailslot; \
typedef prefix ## _any<HANDLE,close_handle,invalid_handle_t,6> prefix ## _pipe; \
typedef prefix ## _any<HANDLE,close_handle> prefix ## _handle; \
typedef prefix ## _any<HANDLE,close_handle,null_t,1> prefix ## _access_token; \
typedef prefix ## _any<HANDLE,close_handle,null_t,2> prefix ## _event; \
typedef prefix ## _any<HANDLE,close_handle,null_t,3> prefix ## _file_mapping; \
typedef prefix ## _any<HANDLE,close_handle,null_t,4> prefix ## _job; \
typedef prefix ## _any<HANDLE,close_handle,null_t,5> prefix ## _mutex; \
typedef prefix ## _any<HANDLE,close_handle,null_t,6> prefix ## _process; \
typedef prefix ## _any<HANDLE,close_handle,null_t,7> prefix ## _semaphore; \
typedef prefix ## _any<HANDLE,close_handle,null_t,8> prefix ## _thread; \
typedef prefix ## _any<HANDLE,close_handle,null_t,9> prefix ## _timer; \
typedef prefix ## _any<HANDLE,close_handle,null_t,10> prefix ## _completion_port; \
typedef prefix ## _any<HDC,close_hdc> prefix ## _hdc; \
typedef prefix ## _any<HICON,close_hicon> prefix ## _hicon; \
typedef prefix ## _any<HMENU,close_hmenu> prefix ## _hmenu; \
typedef prefix ## _any<HCURSOR,close_hcursor> prefix ## _hcursor; \
typedef prefix ## _any<HPEN,close_hgdiobj,null_t,1> prefix ## _hpen; \
typedef prefix ## _any<HRGN,close_hgdiobj,null_t,2> prefix ## _hrgn; \
typedef prefix ## _any<HFONT,close_hgdiobj,null_t,3> prefix ## _hfont; \
typedef prefix ## _any<HBRUSH,close_hgdiobj,null_t,4> prefix ## _hbrush; \
typedef prefix ## _any<HBITMAP,close_hgdiobj,null_t,5> prefix ## _hbitmap; \
typedef prefix ## _any<HPALETTE,close_hgdiobj,null_t,6> prefix ## _hpalette; \
typedef prefix ## _any<HACCEL,close_haccel> prefix ## _haccel; \
typedef prefix ## _any<HWND,close_window> prefix ## _window; \
typedef prefix ## _any<HINSTANCE,close_library> prefix ## _library; \
typedef prefix ## _any<LPVOID,close_file_view> prefix ## _file_view; \
typedef prefix ## _any<LPVOID,close_virtual_free> prefix ## _virtual_ptr; \
typedef prefix ## _any<HANDLE,close_heap_destroy> prefix ## _heap; \
typedef prefix ## _any<HLOCAL,close_local_free> prefix ## _hlocal; \
typedef prefix ## _any<HDESK,close_hdesk> prefix ## _hdesk; \
typedef prefix ## _any<HHOOK,close_hhook> prefix ## _hhook; \
typedef prefix ## _any<HWINSTA,close_hwinsta> prefix ## _hwinsta; \
typedef prefix ## _any<HANDLE,close_event_source> prefix ## _event_source; \
typedef prefix ## _any<HGLOBAL,close_global_free> prefix ## _hglobal;
#endif
//
// Define some other useful typedefs
//
#ifdef _OLEAUTO_H_
# undef DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO
# define DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix) \
typedef prefix ## _any<BSTR,close_bstr> prefix ## _bstr;
#endif
#ifdef __MSGQUEUE_H__
# undef DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE
# define DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix) \
typedef prefix ## _any<HANDLE,close_msg_queue> prefix ## _msg_queue;
#endif
#if defined(_WININET_) | defined(_DUBINET_)
# undef DECLARE_SMART_ANY_TYPEDEFS_WININET
# define DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix) \
typedef prefix ## _any<HINTERNET,close_hinternet> prefix ## _hinternet;
#endif
#ifdef _RAS_H_
# undef DECLARE_SMART_ANY_TYPEDEFS_RAS
# define DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix) \
typedef prefix ## _any<HRASCONN,close_hrasconn> prefix ## _hrasconn;
#endif
#ifdef __RPCDCE_H__
# undef DECLARE_SMART_ANY_TYPEDEFS_RPCDCE
# ifdef UNICODE
# define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix) \
typedef prefix ## _any<RPC_BINDING_HANDLE,close_rpc_binding> prefix ## _rpc_binding; \
typedef prefix ## _any<RPC_BINDING_VECTOR __RPC_FAR*,close_rpc_vector> prefix ## _rpc_binding_vector; \
typedef prefix ## _any<unsigned char __RPC_FAR*,close_rpc_string> prefix ## _rpc_string_A; \
typedef prefix ## _any<unsigned short __RPC_FAR*,close_rpc_string> prefix ## _rpc_string_W; \
typedef prefix ## _rpc_string_W prefix ## _rpc_string;
# else
# define DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix) \
typedef prefix ## _any<RPC_BINDING_HANDLE,close_rpc_binding> prefix ## _rpc_binding; \
typedef prefix ## _any<RPC_BINDING_VECTOR __RPC_FAR*,close_rpc_vector> prefix ## _rpc_binding_vector; \
typedef prefix ## _any<unsigned char __RPC_FAR*,close_rpc_string> prefix ## _rpc_string_A; \
typedef prefix ## _any<unsigned short __RPC_FAR*,close_rpc_string> prefix ## _rpc_string_W; \
typedef prefix ## _rpc_string_A prefix ## _rpc_string;
# endif
#endif
#ifdef _WINSVC_
# undef DECLARE_SMART_ANY_TYPEDEFS_WINSVC
# define DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix) \
typedef prefix ## _any<SC_HANDLE,close_service> prefix ## _service; \
typedef prefix ## _any<SC_LOCK,unlock_service> prefix ## _service_lock;
#endif
#ifdef _WINSOCKAPI_
# undef DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI
# define DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix) \
typedef prefix ## _any<SOCKET,close_socket,invalid_socket_t> prefix ## _socket;
#endif
#if defined(_OBJBASE_H_) & !defined(SMART_ANY_CO_INIT)
# define SMART_ANY_CO_INIT
inline HRESULT smart_co_init_helper( DWORD dwCoInit )
{
(void) dwCoInit;
# if (_WIN32_WINNT >= 0x0400 ) | defined(_WIN32_DCOM)
return ::CoInitializeEx(0,dwCoInit);
# else
return ::CoInitialize(0);
# endif
}
inline void smart_co_uninit_helper( HRESULT hr )
{
if (SUCCEEDED(hr))
::CoUninitialize();
}
typedef close_fun<void(*)(HRESULT),smart_co_uninit_helper> close_co;
typedef value_const<HRESULT,CO_E_NOTINITIALIZED> co_not_init;
# undef DECLARE_SMART_ANY_TYPEDEFS_OBJBASE
# define DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix) \
typedef prefix ## _any<LPVOID,close_co_task_free> prefix ## _co_task_ptr;
#endif
#define DECLARE_SMART_ANY_TYPEDEFS(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_STDIO(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_WINDOWS(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_OLEAUTO(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_MSGQUEUE(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_WININET(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_RAS(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_RPCDCE(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_WINSVC(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_WINSOCKAPI(prefix) \
DECLARE_SMART_ANY_TYPEDEFS_OBJBASE(prefix)