// bdlb_transparenthash.h -*-C++-*- #ifndef INCLUDED_BDLB_TRANSPARENTHASH #define INCLUDED_BDLB_TRANSPARENTHASH #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a transparent hash functor. // //@CLASSES: // bdlb::TransparentHash: a transparent hash functor // //@SEE_ALSO: bsl_map, bsl_set // //@DESCRIPTION: This component provides a 'struct', 'bdlb::TransparentHash', // that defines a functor to generate a hash code for different types and can // be used as transparent hash functor for heterogeneous lookup. // // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic Use of 'bdlb::TransparentHash' /// - - - - - - - - - - - - - - - - - - - - - - - - - // Suppose we need a container to store set of 'bsl::string' unique objects. // 'bsl::unordered_set' is designed exactly for this purpose. But imagine that // we want to use 'bsl::string_view' objects for search operations within our // container. 'bsl::unordered_set' uses 'bsl::hash' as default hash functor. // The problem is that even though the hash function for 'bsl::string_view' // exists, compiler tries to convert 'bsl::string_view' objects to the // 'bsl::string' since 'bsl::hash' is parameterized by 'bsl::string'. And // compilation fails, because there is no such implicit conversion. In // addition, implicit conversions where they are available, may lead to // additional memory allocation for temporary objects. The following code // illustrates how to use 'bdlb::TransparentHash' as a hash functor for the // standard container 'unordered_set', in this case to allow a // 'bsl::unordered_set<bsl::string>' to be searched with a 'bsl::string_view'. // // First, we create a container that usesn'bdlb::TransparentHash'. Note that // to avoid implicit conversions we also have to use a transparent comparator: //.. // typedef bsl::unordered_set<bsl::string, // bdlb::TransparentHash, // bdlb::TransparentEqualTo> TransparentHashSet; // // TransparentHashSet transparentSet; //.. // Now, we fill the container with the strings: //.. // transparentSet.insert("NY"); // transparentSet.insert("LA"); //.. // Finally, we observe that the container allows to use 'bsl::string_view' // objects as a key and does not make any implicit conversions: //.. // bsl::string_view newYork ("NY"); // bsl::string_view losAngeles ("LA"); // bsl::string_view sanFrancisco("SF"); // // assert(transparentSet.end() != transparentSet.find(newYork )); // assert(transparentSet.end() != transparentSet.find(losAngeles )); // assert(transparentSet.end() == transparentSet.find(sanFrancisco)); //.. #include <bdlscm_version.h> #include <bslmf_istriviallycopyable.h> #include <bslmf_istriviallydefaultconstructible.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsl_functional.h> namespace BloombergLP { namespace bdlb { // ====================== // struct TransparentHash // ====================== struct TransparentHash { // This 'struct' defines a hash operation for different types, enabling // them for use for heterogeneous lookup in the standard associative // containers such as 'bsl::unordered_map'. Note that this class is an // empty POD type. // TYPES typedef void is_transparent; // Type alias indicating this is a transparent hash functor. // CREATORS //! TransparentHash() = default; // Create a 'TransparentHash' object. //! TransparentHash(const TransparentHash& original) = default; // Create a 'TransparentHash' object. Note that as 'TransparentHash' // is an empty (stateless) type, this operation has no observable // effect. //! ~TransparentHash() = default; // Destroy this object. // MANIPULATORS //! TransparentHash& operator=(const TransparentHash& rhs) = default; // Assign to this object the value of the specified 'rhs' object, and // return a reference providing modifiable access to this object. // Note that as 'TransparentHash' is an empty (stateless) type, this // operation has no observable effect. // ACCESSORS template <class TYPE> std::size_t operator()(const TYPE &value) const; // Return a hash code generated from the contents of the specified // 'value'. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // --------------------- // struct TransparentHash // --------------------- // ACCESSORS template <class TYPE> inline std::size_t TransparentHash::operator()(const TYPE& value) const { return bsl::hash<TYPE>().operator()(value); } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2021 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 ----------------------------------