как бы передать в шаблон NULL или INVALID_HANDLE_VALUE
От: gid_vvp  
Дата: 28.08.06 15:00
Оценка:
Hi All

есть такой класс

template<
            typename TyHandle, 
            TyHandle (*TyInvalidValue)(), 
            void (*TyHandleClose)(TyHandle)
        >
class HandlePolicy
{
public:
    typedef TyHandle HandleType;
        
    static HandleType InvalidValue()
    {
        return TyInvalidValue();
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            TyHandleClose(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
};


сейчас используется так:

namespace fp
{
    HANDLE InvalidValue()
    {
        return INVALID_HANDLE_VALUE;
    }

    void HandleClose(HANDLE handle)
    {
        ::CloseHandle(handle);
    }
}

namespace sp
{
    HANDLE InvalidValue()
    {
        return INVALID_HANDLE_VALUE;
    }

    void HandleClose(HANDLE handle)
    {
        ::FindClose(handle);
    }
}

namespace ep
{
    HANDLE InvalidValue()
    {
        return NULL;
    }

    void HandleClose(HANDLE handle)
    {
        ::CloseHandle(handle);
    }
}

namespace mp
{
    HMODULE InvalidValue()
    {
        return NULL;
    }

    void HandleClose(HMODULE handle)
    {
        ::FreeLibrary(handle);
    }
}

...

typedef HandlePolicy<HANDLE, &fp::InvalidValue, &fp::HandleClose> FileHandlePolicy;
typedef HandlePolicy<HANDLE, &sp::InvalidValue, &sp::HandleClose> SearchHandlePolicy;
typedef HandlePolicy<HANDLE, &ep::InvalidValue, &ep::HandleClose> EventHandlePolicy;
typedef HandlePolicy<HMODULE, &mp::InvalidValue, &mp::HandleClose> ModuleHandlePolicy;

...



как бы так извернуться, чтоб можно было делать так, вместо того что выше:

typedef HandlePolicy<HANDLE, INVALID_HANDLE_VALUE, &::CloseHandle> FileHandlePolicy;
typedef HandlePolicy<HANDLE, INVALID_HANDLE_VALUE, &::FindClose> SearchHandlePolicy;
typedef HandlePolicy<HANDLE, NULL, &::CloseHandle> EventHandlePolicy;
typedef HandlePolicy<HMODULE,NULL, &::FreeLibrary> ModuleHandlePolicy;

...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: как бы передать в шаблон NULL или INVALID_HANDLE_VALUE
От: Константин Л. Франция  
Дата: 28.08.06 15:49
Оценка: 2 (1)
Здравствуйте, gid_vvp, Вы писали:

_>Hi All


_>есть такой класс


_>
_>template<
_>            typename TyHandle, 
_>            long InvalidValue, 
_>            void (*TyHandleClose)(TyHandle)
        >>
_>class HandlePolicy
_>{
_>public:
_>    typedef TyHandle HandleType;
        
_>    static HandleType InvalidValue()
_>    {
_>        return (HandleType)InvalidValue;
_>    }

_>    static void HandleClose(HandleType handle)
_>    {
_>        if (IsValid(handle))
_>        {
_>            TyHandleClose(handle);
_>        }
_>    }

_>    static bool IsValid(HandleType handle)
_>    {
_>        return (handle != InvalidValue());
_>    }
_>};

_>
Re: как бы передать в шаблон NULL или INVALID_HANDLE_VALUE
От: Left2 Украина  
Дата: 28.08.06 16:18
Оценка:
ИМХО, ты задумал неудачную идею. Я бы юзал классы-traits вместо функций обёрнутых в namespace. Писанины немногим меньше, а гибкость выше — можешь наследовать их друг от друга, можешь добавить какие-то методы без изменения основного интерфейса.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 16:20
Оценка:
_>>
_>>            long InvalidValue, 
_>>


а почему long ?
а другие варианты?

а как быть со функцией закрытия хандла (чтоб можно было передать оригинальную непосредстаенно в шаблон)?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 16:24
Оценка:
INVALID_HANDLE_VALUE не прокатывает
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 16:27
Оценка:
L>ИМХО, ты задумал неудачную идею. Я бы юзал классы-traits вместо функций обёрнутых в namespace. Писанины немногим меньше, а гибкость выше — можешь наследовать их друг от друга, можешь добавить какие-то методы без изменения основного интерфейса.

были traits...
но получалось что для новых хандлов они получались одинаковыми смотри что было:
class FileHandlePolicy
{
public:
    typedef HANDLE HandleType;

    static HandleType InvalidValue()
    {
        return INVALID_HANDLE_VALUE;
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            ::CloseHandle(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
};

class SearchHandlePolicy
{
public:
    typedef HANDLE HandleType;

    static HandleType InvalidValue()
    {
        return INVALID_HANDLE_VALUE;
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            ::FindClose(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
};

class EventHandlePolicy
{
public:
    typedef HANDLE HandleType;

    static HandleType InvalidValue()
    {
        return NULL;
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            ::CloseHandle(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
} ;

class ModuleHandlePolicy
{
public:

    typedef HMODULE HandleType;

    static HandleType InvalidValue()
    {
        return NULL;
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            ::FreeLibrary(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
};



а теперь сравни с тем что хочется:

typedef HandlePolicy<HANDLE, INVALID_HANDLE_VALUE, &::CloseHandle> FileHandlePolicy;
typedef HandlePolicy<HANDLE, INVALID_HANDLE_VALUE, &::FindClose> SearchHandlePolicy;
typedef HandlePolicy<HANDLE, NULL, &::CloseHandle> EventHandlePolicy;
typedef HandlePolicy<HMODULE,NULL, &::FreeLibrary> ModuleHandlePolicy;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 16:36
Оценка:
_>INVALID_HANDLE_VALUE не прокатывает
только вот так:

typedef HandlePolicy<HANDLE,    (LONGLONG)INVALID_HANDLE_VALUE,    &fp::HandleClose> FileHandlePolicy;


что то не очень мне нравиться...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: Константин Л. Франция  
Дата: 28.08.06 17:00
Оценка:
Здравствуйте, gid_vvp, Вы писали:

_>>>
_>>>            long InvalidValue, 
_>>>


_>а почему long ?


писал по-памяти. Думал INVALID_HANDLE_VALUE это лонг

_>а другие варианты?


_>а как быть со функцией закрытия хандла (чтоб можно было передать оригинальную непосредстаенно в шаблон)?


_>>[ccode]

_>>template<
_>> typename TyHandle,
_>> TyHandle InvalidValue, //так может прокатить. Можно попробовать заменить на void*
typename TyHandleCloseReturnType,
_>> TyHandleCloseReturnType ( /*__stdcall ???*/ *TyHandleClose)(TyHandle)
>>>
_>>class HandlePolicy
_>>{
_>>public:
_>> typedef TyHandle HandleType;

_>> static HandleType InvalidValue()

_>> {
_>> return InvalidValue;
_>> }

_>> static TyHandleCloseReturnType HandleClose(HandleType handle)

_>> {
_>> if (IsValid(handle))
_>> {
_>> return TyHandleClose(handle);
_>> }
_>> return TyHandleCloseReturnType();//временно, см комментарий
_>> }

_>> static bool IsValid(HandleType handle)

_>> {
_>> return (handle != InvalidValue());
_>> }
_>>};

Для HandleClose, похоже, придется писать спецификацию для типов void и BOOL(int).
Re[4]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: Константин Л. Франция  
Дата: 28.08.06 17:06
Оценка: 3 (1)
Здравствуйте, Константин Л., Вы писали:

сорри:

[ccode]
template<
typename TyHandle,
TyHandle InvalidValue, //так может прокатить. Можно попробовать заменить на void*
typename TyHandleCloseReturnType,
TyHandleCloseReturnType ( /*__stdcall ???*/ *TyHandleClose)(TyHandle)
>
class HandlePolicy
{
public:
typedef TyHandle HandleType;

static HandleType InvalidValue()
{
return InvalidValue;
}

static TyHandleCloseReturnType HandleClose(HandleType handle)
{
if (IsValid(handle))
{
return TyHandleClose(handle);
}
return TyHandleCloseReturnType();//временно, см комментарий
}

static bool IsValid(HandleType handle)
{
return (handle != InvalidValue());
}
};
Re[5]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: Константин Л. Франция  
Дата: 28.08.06 17:08
Оценка:
Здравствуйте, Константин Л., Вы писали:

сорри повторно

template<
     typename TyHandle, 
     TyHandle InvalidValue, //так может прокатить. Можно попробовать заменить на void* 
     typename TyHandleCloseReturnType,
     TyHandleCloseReturnType ( /*__stdcall ???*/ *TyHandleClose)(TyHandle) 
>
class HandlePolicy
{
public:
     typedef TyHandle HandleType;

     static HandleType InvalidValue()
     {
          return InvalidValue;
     }

     static TyHandleCloseReturnType HandleClose(HandleType handle)
     {
          if (IsValid(handle))
          {
               return TyHandleClose(handle);
          } 
          return TyHandleCloseReturnType();//временно, см комментарий 
     }

     static bool IsValid(HandleType handle)
     {
          return (handle != InvalidValue());
     }
};
Re[5]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 17:10
Оценка:
template<
     typename TyHandle, 
     TyHandle InvalidValue, //так может прокатить. Можно попробовать заменить на void*


это не прокатит, а вот void* похоже самое то
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 17:24
Оценка:
с функцией закрытия хандлов я намутил
они оказывается одинаковый прототип имеют и такое вполне прокатит...
пока не найдётся какая-нибудь не укладывающаяся сюда

КЛ>
КЛ>template<
КЛ>     typename TyHandleCloseReturnType,
КЛ>     BOOL ( WINAPI *TyHandleClose)(TyHandle) 
>>
КЛ>
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 28.08.06 17:28
Оценка:
окончательный вариант

template<
            typename TyHandle, 
            void* TyInvalidValue, 
            BOOL (WINAPI * TyHandleClose)(TyHandle)
        >
class HandlePolicy
{
public:
    typedef TyHandle HandleType;
        
    static HandleType InvalidValue()
    {
        return static_cast<HandleType>(TyInvalidValue);
    }

    static void HandleClose(HandleType handle)
    {
        if (IsValid(handle))
        {
            TyHandleClose(handle);
        }
    }

    static bool IsValid(HandleType handle)
    {
        return (handle != InvalidValue());
    }
};



typedef HandlePolicy<HANDLE,  INVALID_HANDLE_VALUE, &::CloseHandle> FileHandlePolicy;
typedef HandlePolicy<HANDLE,  INVALID_HANDLE_VALUE, &::FindClose>   SearchHandlePolicy;
typedef HandlePolicy<HANDLE,  NULL,                 &::CloseHandle> EventHandlePolicy;
typedef HandlePolicy<HMODULE, NULL,                 &::FreeLibrary> ModuleHandlePolicy;
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: как бы передать в шаблон NULL или INVALID_HANDLE_VALUE
От: IceStudent Украина  
Дата: 28.08.06 18:40
Оценка:
Здравствуйте, gid_vvp, Вы писали:

_>Hi All


_>есть такой класс


А как насчёт альтернативы? Правда, это только для HANDLE. Для SOCKET, например, пришлось писать другой тип из-за специфичности.

struct SystemCloseHandlePolicy
{
    static inline BOOL CloseHandle(HANDLE h)
    {
        return ::CloseHandle(h);
    }
};

template<bool duplicate_t,class CloseHandlePolicy = SystemCloseHandlePolicy>
class CHandleEx_t
{
public:
    ...
    void Close() throw()
    {
        if(IsValid())
            CloseHandlePolicy::CloseHandle(this->m_h);
        this->m_h = NULL;
    }
    ...
}
--
wbr, icestudent
Re[3]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: IceStudent Украина  
Дата: 29.08.06 05:52
Оценка:
Здравствуйте, gid_vvp, Вы писали:

_>были traits...

_>но получалось что для новых хандлов они получались одинаковыми смотри что было:
Было бы использовать свойство для получения неверного значения хэндла (лучше функция, т.к. неверными могут быть и NULL, и -1 одновременно), а стратегию — для закрытия хэндла. Тогда одно свойство можно использовать в комбинации с разными стратегиями.
--
wbr, icestudent
Re[4]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 29.08.06 06:48
Оценка:
IS>Было бы использовать свойство для получения неверного значения хэндла (лучше функция, т.к. неверными могут быть и NULL, и -1 одновременно), а стратегию — для закрытия хэндла. Тогда одно свойство можно использовать в комбинации с разными стратегиями.

откуда дровишки?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: gid_vvp  
Дата: 29.08.06 06:48
Оценка:
IS>А как насчёт альтернативы? Правда, это только для HANDLE. Для SOCKET, например, пришлось писать другой тип из-за специфичности.

IS>
struct SystemCloseHandlePolicy
IS>{
IS>    static inline BOOL CloseHandle(HANDLE h)
IS>    {
IS>        return ::CloseHandle(h);
IS>    }
IS>};

IS>template<bool duplicate_t,class CloseHandlePolicy = SystemCloseHandlePolicy>
IS>class CHandleEx_t
IS>{
IS>public:
IS>    ...
IS>    void Close() throw()
IS>    {
IS>        if(IsValid())
IS>            CloseHandlePolicy::CloseHandle(this->m_h);
        this->>m_h = NULL;
IS>    }
IS>    ...
IS>}


не могу уловить фишку...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: Left2 Украина  
Дата: 29.08.06 07:52
Оценка:
А для того чтобы они не получались одинаковыми есть такая замечательная вещь как наследование. Причём поскольку функции тут только статик, то ты запросто можешь юзать даже множественное наследование (никаких оверхедов не будет).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: IceStudent Украина  
Дата: 29.08.06 08:13
Оценка:
Здравствуйте, gid_vvp, Вы писали:

IS>>Было бы использовать свойство для получения неверного значения хэндла (лучше функция, т.к. неверными могут быть и NULL, и -1 одновременно), а стратегию — для закрытия хэндла. Тогда одно свойство можно использовать в комбинации с разными стратегиями.


_>откуда дровишки?

Из-за инициализации HANDLE через NULL, а не INVALID_HANDLE_VALUE (в том же ATL::CHandle или если принимаешь уже инициализированный так HANDLE).
--
wbr, icestudent
Re[3]: как бы передать в шаблон NULL или INVALID_HANDLE_VALU
От: IceStudent Украина  
Дата: 29.08.06 08:13
Оценка:
Здравствуйте, gid_vvp, Вы писали:

_>не могу уловить фишку...

Ну это то, о чём я говорил выше, что вместо значения использовать функцию, проверяющую хэндл на валидность. Но с другой стороны — можно взять за правило инициализацию через -1, тогда проблема отпадает.
--
wbr, icestudent
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.