/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright 2015 Danny Robson <danny@nerdcruft.net>
 */

#ifndef __UTIL_MEMORY_DELETER_HPP
#define __UTIL_MEMORY_DELETER_HPP

#include <functional>

namespace cruft::memory {
    template <typename T>
    class func_deleter {
    public:
        using func_t = std::function<void(T*)>;

        explicit func_deleter (func_t _func):
            m_func (_func)
        { ; }

        inline void operator() (T *t)
        { m_func (t); }

    private:
        func_t m_func;
    };


    // dispatch object deletion to a known member function.
    //
    // XXX: Generates a "sorry, unimplemented" under GCC (which is
    // effectively an ICE). Their bug tracker seems to indicate they don't
    // give a fuck, so we can't use this except under clang.
    template <
        typename ValueT,
        typename OwnerT,
        void (OwnerT::*Func)(ValueT*)
    >
    class owner_deleter {
    public:
        owner_deleter (OwnerT &owner):
            m_owner (owner)
        { ; }

        inline void operator() (ValueT *t)
        {
            (m_owner.*Func) (t);
        }

    private:
        OwnerT& m_owner;
    };
}

#endif