Share via


STL functors, scoped handles and how we can use them in Windows programming - scoped_handle

#pragma once

#include <memory>

#include <cassert>

template<typename HANDLE_TYPE, HANDLE_TYPE UNDEFINED_VALUE>

class scoped_handle

{

private:

    class invoker_base

    {

    public:

        virtual ~invoker_base() {}

    public:

        virtual void invoke(HANDLE_TYPE handle) = 0;

    protected:

        explicit invoker_base() {}

    private:

        explicit invoker_base(const invoker_base &);

        invoker_base &operator=(const invoker_base &);

    };

    template<typename CALLABLE_TYPE>

    class invoker : public invoker_base

    {

    public:

        explicit invoker(CALLABLE_TYPE callable) : _callable(callable) {}

        virtual ~invoker() {}

    public:

        virtual void invoke(HANDLE_TYPE handle) {_callable(handle);}

    private:

        CALLABLE_TYPE _callable;

    private:

        explicit invoker();

        explicit invoker(const invoker &);

        invoker &operator=(const invoker &);

    };

public:

    template<typename CALLABLE_TYPE>

    explicit scoped_handle(HANDLE_TYPE value, CALLABLE_TYPE callable_deleter)

        : _value(value), _deleter_invoker_ptr(new invoker<CALLABLE_TYPE>(callable_deleter)) {}

    ~scoped_handle()

    {

        release();

    }

    operator HANDLE_TYPE()

    {

        assert(UNDEFINED_VALUE != _value && "Must set encapsulated handle first");

        return _value;

    }

    operator bool()

    {

        return UNDEFINED_VALUE != _value;

    }

    HANDLE_TYPE *operator&()

    {

        assert(UNDEFINED_VALUE == _value && "Must release encapsulated handle first");

        return &_value;

    }

    void operator=(HANDLE_TYPE value)

    {

        if (_value == value)

            return;

        release();

        _value = value;

  }

private:

    void release()

    {

        if (UNDEFINED_VALUE != _value)

        {

            try

            {

                _deleter_invoker_ptr->invoke(_value);

            }

            catch (...)

            {

            }

        }

    }

private:

    HANDLE_TYPE _value;

    std::auto_ptr<invoker_base> _deleter_invoker_ptr;

private:

    explicit scoped_handle();

    explicit scoped_handle(const scoped_handle &);

    scoped_handle &operator=(const scoped_handle &);

};

 

scoped_handle.h

Comments

  • Anonymous
    November 04, 2008
    Firstly, it's election day so get out there and vote! Secondly, I went to bed last night and dreamt about

  • Anonymous
    September 14, 2011
    Should have a look  to boost::shared_ptr with a custom deleter. Copied from stackoverflow.com/.../1556219