// bslstl_ownerless.h -*-C++-*- #ifndef INCLUDED_BSLSTL_OWNERLESS #define INCLUDED_BSLSTL_OWNERLESS #include <bsls_ident.h> BSLS_IDENT("$Id$ $CSID$") //@PURPOSE: Provide an ordering for shared and weak pointers. // //@CLASSES: // bsl::owner_less: ordering comparator for 'shared_ptr' and 'weak_ptr' // //@CANONICAL_HEADER: bsl_memory.h // //@SEE_ALSO: bslstl_sharedptr // //@DESCRIPTION: This component provides the C+11 standard binary comparison // functor, 'bsl::owner_less', that determines the order of two smart pointer // objects by the relative order of the address of their 'bslma::SharedPtrRep' // data. Note that this class is an empty POD type. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Basic Use of 'owner_less<void>' /// - - - - - - - - - - - - - - - - - - - - - // Suppose we need a map accepting shared pointers as keys. We also expect // that this container will be accessible from multiple threads and some of // them will store weak versions of smart pointers to break reference cycles. // To avoid excessive conversions we can use a transparent comparator to // enable heterogeneous lookup with 'bsl::weak_ptr' objects as parameters for // search functions. // // First, we create a container and populate it: //.. // typedef bsl::map<bsl::shared_ptr<int>, int, bsl::owner_less<void> > // Map; // Map container; // // bsl::shared_ptr<int> sharedPtr1 = bsl::make_shared<int>(1); // bsl::shared_ptr<int> sharedPtr2 = bsl::make_shared<int>(2); // bsl::weak_ptr<int> weakPtr1(sharedPtr1); // // container[sharedPtr1] = 1; // container[sharedPtr2] = 2; //.. // Now, we make sure, that shared pointers can be used to perform lookup: //.. // Map::const_iterator iter = container.find(sharedPtr1); // assert(container.end() != iter ); // assert(1 == iter->second); // // iter = container.find(sharedPtr2); // assert(container.end() != iter); // assert(2 == iter->second); //.. // Finally, we simulate the situation of accessing the container from another // thread and perform lookup using weak pointers: //.. // iter = container.find(weakPtr1); // assert(container.end() != iter ); // assert(1 == iter->second); // // bsl::weak_ptr<int> weakPtr3(bsl::make_shared<int>(3)); // iter = container.find(weakPtr3); // assert(container.end() == iter); //.. #include <bslscm_version.h> #include <bslstl_sharedptr.h> #include <bsls_keyword.h> // 'BSLS_KEYWORD_NOEXCEPT' namespace bsl { template <class POINTER_TYPE = void> struct owner_less; template <class ELEMENT_TYPE> struct owner_less<shared_ptr<ELEMENT_TYPE> >; template <class ELEMENT_TYPE> struct owner_less<weak_ptr<ELEMENT_TYPE> >; template <> struct owner_less<void>; // C++11 Compatibility template <class ELEMENT_TYPE> struct owner_less<shared_ptr<ELEMENT_TYPE> > { // TYPES typedef bool result_type; typedef shared_ptr<ELEMENT_TYPE> first_argument_type; typedef shared_ptr<ELEMENT_TYPE> second_argument_type; // CREATORS //! owner_less() = default; // Create an 'owner_less' object. //! owner_less(const owner_less& original) = default; // Create an 'owner_less' object. Note that as 'owner_less' is an // empty (stateless) type, this operation has no observable effect. //! ~owner_less() = default; // Destroy this object. // MANIPULATORS //! owner_less& operator=(const owner_less& 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 'owner_less' is an empty (stateless) type, this operation // has no observable effect. // ACCESSORS bool operator()(const shared_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; bool operator()(const shared_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; bool operator()(const weak_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; // Return 'true' if the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'a' // is ordered before the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'b' // under the total ordering supplied by // 'std::less<BloombergLP::bslma::SharedPtrRep *>', and 'false' // otherwise. }; template <class ELEMENT_TYPE> struct owner_less<weak_ptr<ELEMENT_TYPE> > { // TYPES typedef bool result_type; typedef weak_ptr<ELEMENT_TYPE> first_argument_type; typedef weak_ptr<ELEMENT_TYPE> second_argument_type; // CREATORS //! owner_less() = default; // Create an 'owner_less' object. //! owner_less(const owner_less& original) = default; // Create an 'owner_less' object. Note that as 'owner_less' is an // empty (stateless) type, this operation has no observable effect. //! ~owner_less() = default; // Destroy this object. // MANIPULATORS //! owner_less& operator=(const owner_less& 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 'owner_less' is an empty (stateless) type, this operation // has no observable effect. // ACCESSORS bool operator()(const weak_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; bool operator()(const shared_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; bool operator()(const weak_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT; // Return 'true' if the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'a' // is ordered before the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'b' // under the total ordering supplied by // 'std::less<BloombergLP::bslma::SharedPtrRep *>', and 'false' // otherwise. }; template<> struct owner_less<void> { // TYPES typedef void is_transparent; // Type alias indicating this is a transparent comparator. // CREATORS //! owner_less() = default; // Create an 'owner_less' object. //! owner_less(const owner_less& original) = default; // Create an 'owner_less' object. Note that as 'owner_less' is an // empty (stateless) type, this operation has no observable effect. //! ~owner_less() = default; // Destroy this object. // MANIPULATORS //! owner_less& operator=(const owner_less& 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 'owner_less' is an empty (stateless) type, this operation // has no observable effect. // ACCESSORS template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> bool operator()(const shared_ptr<ELEMENT_TYPE_A> &a, const shared_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT; template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> bool operator()(const shared_ptr<ELEMENT_TYPE_A> &a, const weak_ptr< ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT; template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> bool operator()(const weak_ptr< ELEMENT_TYPE_A> &a, const shared_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT; template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> bool operator()(const weak_ptr<ELEMENT_TYPE_A> &a, const weak_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT; // Return 'true' if the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'a' // is ordered before the address of the // 'BloombergLP::bslma::SharedPtrRep' object used by the specified 'b' // under the total ordering supplied by // 'std::less<BloombergLP::bslma::SharedPtrRep *>', and 'false' // otherwise. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // -------------------------------------------- // struct owner_less<shared_ptr<ELEMENT_TYPE> > // -------------------------------------------- template <class ELEMENT_TYPE> inline bool owner_less<shared_ptr<ELEMENT_TYPE> >::operator()( const shared_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template <class ELEMENT_TYPE> inline bool owner_less<shared_ptr<ELEMENT_TYPE> >::operator()( const shared_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template <class ELEMENT_TYPE> inline bool owner_less<shared_ptr<ELEMENT_TYPE> >::operator()( const weak_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } // ------------------------------------------ // struct owner_less<weak_ptr<ELEMENT_TYPE> > // ------------------------------------------ template <class ELEMENT_TYPE> inline bool owner_less<weak_ptr<ELEMENT_TYPE> >::operator()( const weak_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template <class ELEMENT_TYPE> inline bool owner_less<weak_ptr<ELEMENT_TYPE> >::operator()( const shared_ptr<ELEMENT_TYPE>& a, const weak_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template <class ELEMENT_TYPE> inline bool owner_less<weak_ptr<ELEMENT_TYPE> >::operator()( const weak_ptr<ELEMENT_TYPE>& a, const shared_ptr<ELEMENT_TYPE>& b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } // ----------------------- // struct owner_less<void> // ----------------------- template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> inline bool owner_less<void>::operator()( const shared_ptr<ELEMENT_TYPE_A> &a, const shared_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> inline bool owner_less<void>::operator()( const shared_ptr<ELEMENT_TYPE_A> &a, const weak_ptr< ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> inline bool owner_less<void>::operator()( const weak_ptr< ELEMENT_TYPE_A> &a, const shared_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } template<class ELEMENT_TYPE_A, class ELEMENT_TYPE_B> inline bool owner_less<void>::operator()( const weak_ptr<ELEMENT_TYPE_A> &a, const weak_ptr<ELEMENT_TYPE_B> &b) const BSLS_KEYWORD_NOEXCEPT { return a.owner_before(b); } // ============================================================================ // TYPE TRAITS // ============================================================================ // Type traits for 'owner_less' //: o 'owner_less' is a stateless POD, trivially constructible and copyable. template<class POINTER_TYPE> struct is_trivially_default_constructible<owner_less<POINTER_TYPE> > : bsl::true_type {}; template<class POINTER_TYPE> struct is_trivially_copyable<owner_less<POINTER_TYPE> > : bsl::true_type {}; } // close namespace bsl #endif // ---------------------------------------------------------------------------- // Copyright 2014 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 ----------------------------------