// bslma_managedptr_factorydeleter.h                                  -*-C++-*-
#ifndef INCLUDED_BSLMA_MANAGEDPTR_FACTORYDELETER
#define INCLUDED_BSLMA_MANAGEDPTR_FACTORYDELETER

#include <bsls_ident.h>
BSLS_IDENT("$Id$ $CSID$")

//@PURPOSE: Provide a factory-based deleter for the managed pointer class.
//
//@CLASSES:
//  bslma::ManagedPtr_FactoryDeleter: deduced deleter used by bslma::ManagedPtr
//
//@SEE_ALSO: bslma_managedptr
//
//@DESCRIPTION: This component provides a utility `struct`,
// `bslma::ManagedPtr_FactoryDeleter`, used as an implementation detail by
// `bslma::ManagedPtr` to produce a type-erasing deleter function that destroys
// an object of (template parameter) `OBJECT_TYPE`, using a factory of
// (template parameter) `FACTORY` type that provides a `deleteObject` method.

#include <bslscm_version.h>

#include <bsls_assert.h>

namespace BloombergLP {
namespace bslma {

                   // ================================
                   // struct ManagedPtr_FactoryDeleter
                   // ================================

/// This utility provides a general deleter for factories that provide a
/// `deleteObject` operation (e.g., `bslma::Allocator`, `bdlma::Pool`).
template <class OBJECT_TYPE, class FACTORY>
struct ManagedPtr_FactoryDeleter {

    // CLASS METHODS

    /// Delete the specified `object` by invoking `deleteObject` on the
    /// specified `factory`, casting `object` to `OBJECT_TYPE *` and
    /// `factory` to `FACTORY *`.  The behavior is undefined unless
    /// `factory` points to an object of type `FACTORY`, and `object` points
    /// to a complete object of type `OBJECT_TYPE` or `OBJECT_TYPE` has a
    /// virtual destructor and `object` points to an object whose dynamic
    /// type derives from 'OBJECT_TYPE.
    static void deleter(void *object, void *factory);
};

// ============================================================================
//                          INLINE DEFINITIONS
// ============================================================================

                    // --------------------------------
                    // struct ManagedPtr_FactoryDeleter
                    // --------------------------------

// CLASS METHODS
template <class OBJECT_TYPE, class FACTORY>
inline
void ManagedPtr_FactoryDeleter<OBJECT_TYPE, FACTORY>::deleter(void *object,
                                                              void *factory)
{
    BSLS_ASSERT_SAFE(0 != object);
    BSLS_ASSERT_SAFE(0 != factory);

    static_cast<FACTORY *>(factory)->deleteObject(
                                           static_cast<OBJECT_TYPE *>(object));
}

}  // close package namespace
}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2016 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
