// bdlb_cstringequalto.h                                              -*-C++-*-
#ifndef INCLUDED_BDLB_CSTRINGEQUALTO
#define INCLUDED_BDLB_CSTRINGEQUALTO

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

//@PURPOSE: Provide a standard compatible equality predicate for C-strings.
//
//@CLASSES:
//  bdlb::CStringEqualTo: a standard compatible C-string equality predicate
//
//@SEE_ALSO:
//
//@DESCRIPTION: This component provides a `struct`, `bdlb::CStringEqualTo`,
// that defines a functor that checks two null-terminated strings for equality
// using a case-sensitive string comparison, rather than simply comparing the
// two addresses (as the `std::equal_to` functor would do).  This comparison
// functor is suitable for supporting C-strings as keys in unordered
// associative containers.  Note that the container behavior would be undefined
// if the strings referenced by such pointers were to change value.
//
///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Basic Use of `bdlb::CStringEqualTo`
/// - - - - - - - - - - - - - - - - - - - - - - -
// The following snippets of code illustrate how to create and use a
// `bdlb::CStringEqualTo` object as a binary predicate for the standard library
// function `bsl::equal` to test that two ranges of null-terminated character
// strings are equal.
//
// First, we create few sequences with null-terminated character strings,
// making sure that their elements have different memory addresses:
// ```
// const char hello1[] = { 'h', 'e', 'l', 'l', 'o', 0};
// const char hello2[] = { 'h', 'e', 'l', 'l', 'o', 0};
//
// const char* arrayA[3] = { "A", "B", hello1 };
// const char* arrayB[3] = { "A", "B", hello2 };
// ```
// Now, use bdlb::CStringEqualTo() as a binary predicate to compare sequences:
// ```
// bool bdlbEqualTo = bsl::equal(arrayA, arrayA+3, arrayB,
//                               bdlb::CStringEqualTo());
// bool bslEqualTo  = bsl::equal(arrayA, arrayA+3, arrayB,
//                               bsl::equal_to<const char *>());
// ```
// Finally, we observe that `bdlb::CStringEqualTo` compares character string by
// their values, while the default comparator compares addresses:
// ```
// assert( true  == bdlbEqualTo );
// assert( false == bslEqualTo );
// ```

#include <bdlscm_version.h>

#include <bslmf_integralconstant.h>
#include <bslmf_istriviallycopyable.h>
#include <bslmf_istriviallydefaultconstructible.h>
#include <bslmf_nestedtraitdeclaration.h>

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

#include <bsl_cstring.h>

namespace BloombergLP {
namespace bdlb {

                       // =====================
                       // struct CStringEqualTo
                       // =====================

/// This `struct` defines a comparison functor on null-terminated character
/// strings, enabling them for use as keys in the standard unordered
/// associative containers such as `bsl::unordered_map` and
/// `bsl::unordered_set`.  Note that this class is an empty POD type.
struct CStringEqualTo {

    // STANDARD TYPEDEFS
    typedef const char *first_argument_type;
    typedef const char *second_argument_type;
    typedef bool        result_type;

    // TRAITS
    BSLMF_NESTED_TRAIT_DECLARATION(CStringEqualTo, bsl::is_trivially_copyable)
    BSLMF_NESTED_TRAIT_DECLARATION(CStringEqualTo,
                                       bsl::is_trivially_default_constructible)

    // CREATORS

    /// Create a `CStringEqualTo` object.
    //! CStringEqualTo() = default;

    /// Create a `CStringEqualTo` object.  Note that as `CStringEqualTo` is
    /// an empty (stateless) type, this operation has no observable effect.
    //! CStringEqualTo(const CStringEqualTo& original) = default;

    /// Destroy this object.
    //! ~CStringEqualTo() = default;

    // MANIPULATORS

    /// Assign to this object the value of the specified `rhs` object, and
    /// return a reference providing modifiable access to this object.  Note
    /// that as `CStringEqualTo` is an empty (stateless) type, this
    /// operation has no observable effect.
    //! CStringEqualTo& operator=(const CStringEqualTo&) = default;

    // ACCESSORS

    /// Return `true` if the specified `lhs` string has the same (case
    /// sensitive) value as the specified `rhs` string, and `false`
    /// otherwise.  The behavior is undefined unless both `lhs` and `rhs`
    /// point to null-terminated strings.
    bool operator()(const char *lhs, const char *rhs) const;
};

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

                       // ---------------------
                       // struct CStringEqualTo
                       // ---------------------

// ACCESSORS
inline
bool CStringEqualTo::operator()(const char *lhs, const char *rhs) const
{
    BSLS_ASSERT(lhs);
    BSLS_ASSERT(rhs);

    return 0 == bsl::strcmp(lhs, rhs);
}

}  // close package namespace
}  // 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 ----------------------------------
