// bdlma_memoryblockdescriptor.h                                      -*-C++-*-

// ----------------------------------------------------------------------------
//                                   NOTICE
//
// This component is not up to date with current BDE coding standards, and
// should not be used as an example for new development.
// ----------------------------------------------------------------------------

#ifndef INCLUDED_BDLMA_MEMORYBLOCKDESCRIPTOR
#define INCLUDED_BDLMA_MEMORYBLOCKDESCRIPTOR

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

//@PURPOSE: Provide a class describing a block of memory.
//
//@CLASSES:
//  bdlma::MemoryBlockDescriptor: describes a block of memory
//
//@SEE_ALSO:
//
//@DESCRIPTION: This component defines an in-core value-semantic class for
// describing a block of memory, namely 'bdlma::MemoryBlockDescriptor'.  Each
// descriptor object contains the address of the block of memory and the size
// of the block.  The distinguished "null" descriptor contains an address and a
// size that are both 0.
//
///Usage
///-----
// This example demonstrates how to create and test the state of a
// 'bdlma::MemoryBlockDescriptor'.
//..
//   char buffer[100];
//
//   bdlma::MemoryBlockDescriptor a(buffer, sizeof buffer);
//                               assert(!a.isNull());
//                               assert(buffer         == a.address());
//                               assert(sizeof buffer  == a.size());
//
//   bdlma::MemoryBlockDescriptor b;
//                               assert( b.isNull());
//                               assert(0              == b.address());
//                               assert(0              == b.size());
//                               assert(a              != b);
//
//   b = a;
//                               assert(!b.isNull());
//                               assert(buffer         == b.address());
//                               assert(sizeof buffer  == b.size());
//                               assert(a              == b);
//
//..

#include <bdlscm_version.h>

#include <bsls_assert.h>
#include <bsls_review.h>
#include <bsls_types.h>

namespace BloombergLP {
namespace bdlma {

                       // ===========================
                       // class MemoryBlockDescriptor
                       // ===========================

class MemoryBlockDescriptor {
    // This is an in-core value-semantic class describing the size and address
    // of a block of memory.  A null block descriptor is defined as a
    // descriptor having an address and size of 0.  The behavior is undefined
    // for a descriptor whose address is 0, but whose size if not also 0.

  public:
    // PUBLIC TYPES
    typedef bsls::Types::size_type size_type;  // type for block size

  private:
    // DATA
    void      *d_address_p;  // address of the memory block
    size_type  d_size;       // size of the block

  public:
    // CREATORS
    MemoryBlockDescriptor();
        // Create a memory block descriptor having an address and size of 0.

    MemoryBlockDescriptor(void *address, size_type size);
        // Create a memory block descriptor having the specified 'address' and
        // 'size'.  The behavior is undefined if 'address' is 0 but 'size' is
        // not also 0.

    MemoryBlockDescriptor(const MemoryBlockDescriptor& original);
        // Create a memory block descriptor having the same value as the
        // specified 'original' descriptor.  Two descriptors have the same
        // value if and only if they have the same address and size.

    // ~MemoryBlockDescriptor();
        // Destroy this memory block descriptor.  Note that this trivial
        // destructor is generated by the compiler.

    // MANIPULATORS
    MemoryBlockDescriptor& operator=(const MemoryBlockDescriptor& rhs);
        // Assign to this memory block descriptor the value of the specified
        // 'rhs' descriptor and return a reference to this modifiable
        // descriptor.

    void setAddressAndSize(void *address, size_type size);
        // Set the address and size of the memory block described by this
        // object to the specified 'address' and
        // 'size.  The behavior is undefined if 'address' is 0 but 'size' is
        // not also 0.

    // ACCESSORS
    bool isNull() const;
        // Return 'true' if this memory block descriptor describes a null
        // memory block and 'false' otherwise.  A null memory block has an
        // address and size of 0.

    void *address() const;
        // Return the address of the modifiable memory block described by this
        // object, or 0 if this is a null descriptor.

    size_type size() const;
        // Return the size of the memory block described by this object.

    void print() const;
        // Format the attributes of this memory block descriptor to 'stdout' in
        // some reasonable (single-line) format.
};

// FREE OPERATORS
bool operator==(const MemoryBlockDescriptor& lhs,
                const MemoryBlockDescriptor& rhs);
    // Return 'true' if the specified 'lhs' and 'rhs' memory block descriptors
    // have the same value and 'false' otherwise.  Two descriptors have the
    // same value if and only if they have the same address and size.

bool operator!=(const MemoryBlockDescriptor& lhs,
                const MemoryBlockDescriptor& rhs);
    // Return 'true' if the specified 'lhs' and 'rhs' memory block descriptors
    // do not have the same value and 'false' otherwise.  Two descriptors
    // differ in value if they differ in either their address or size.

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

                       // ---------------------------
                       // class MemoryBlockDescriptor
                       // ---------------------------

// CREATORS
inline
MemoryBlockDescriptor::MemoryBlockDescriptor()
: d_address_p(0)
, d_size(0)
{
}

inline
MemoryBlockDescriptor::MemoryBlockDescriptor(void      *address,
                                             size_type  size)
: d_address_p(address)
, d_size(size)
{
    BSLS_ASSERT(address || 0 == size);
}

inline
MemoryBlockDescriptor::MemoryBlockDescriptor(
                                         const MemoryBlockDescriptor& original)
: d_address_p(original.d_address_p)
, d_size(original.d_size)
{
}

// MANIPULATORS
inline
MemoryBlockDescriptor& MemoryBlockDescriptor::operator=(
                                              const MemoryBlockDescriptor& rhs)
{
    d_address_p = rhs.d_address_p;
    d_size      = rhs.d_size;

    return *this;
}

inline
void MemoryBlockDescriptor::setAddressAndSize(void *address, size_type size)
{
    BSLS_ASSERT(address || 0 == size);

    d_address_p = address;
    d_size      = size;
}

// ACCESSORS
inline
void *MemoryBlockDescriptor::address() const
{
    return d_address_p;
}

inline
MemoryBlockDescriptor::size_type
MemoryBlockDescriptor::size() const
{
    return d_size;
}

inline
bool MemoryBlockDescriptor::isNull() const
{
    return 0 == d_address_p;
}

}  // close package namespace

// FREE OPERATORS
inline
bool bdlma::operator==(const MemoryBlockDescriptor& lhs,
                       const MemoryBlockDescriptor& rhs)
{
    return lhs.address() == rhs.address() && lhs.size() == rhs.size();
}

inline
bool bdlma::operator!=(const MemoryBlockDescriptor& lhs,
                       const MemoryBlockDescriptor& rhs)
{
    return !(lhs == rhs);
}

}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2015 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 ----------------------------------