// bslalg_swaputil.h -*-C++-*- #ifndef INCLUDED_BSLALG_SWAPUTIL #define INCLUDED_BSLALG_SWAPUTIL #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a simple to use 'swap' algorithm. // //@CLASSES: // bslalg::SwapUtil: namespace for the 'swap' utility function. // //@SEE_ALSO: bsl_algorithm // //@DESCRIPTION: This component provides a namespace for a utility function that // swaps the value of two objects of the same type. Using this utility is // intended to be a simpler alternative to using the standard 'swap' algorithm // directly. The standard 'swap' algorithm is provided in the 'bsl' namespace // in a generic form and overloaded for specific classes in the namespaces of // those classes. When the 'swap' algorithm is used, its specific // implementation is supposed to be found by Argument Dependent Lookup (ADL). // Finding the proper 'swap' function with ADL requires bringing the // 'bsl::swap' into the current scope with the 'using' directive and then // calling a 'swap' function without the namespace qualification. The 'swap' // utility static function provided by this component relieves the end-user // from a need to remember those details of the proper usage of the 'swap' // algorithm. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Using 'bslalg::SwapUtil::swap' ///- - - - - - - - - - - - - - - - - - - - - // In this example we define a type 'Container' and use 'bslalg::SwapUtil' to // both implement a user-defined 'swap' for 'Container', and swap two container // objects. // // We start by defining a class 'Container' in the 'xyz' namespace. Further we // assume that 'Container' has some expensive-to-copy data, so we provide a // custom 'swap' algorithm to efficiently swap the data between a two objects // this class by defining a 'swap' method and a 'swap' free function. //.. // namespace xyz { // // class Container { // private: // int d_expensiveData; // // public: // void swap(Container& other); // // Swap the value of 'this' object with the value of the specified // // 'other' object. This method provides the no-throw // // exception-safety guarantee. // }; // // void swap(Container& a, Container& b); // // Swap the values of the specified 'a' and 'b' objects. This function // // provides the no-throw exception-safety guarantee. //.. // Note that the free function 'swap' is overloaded in the namespace of the // class 'Container', which is 'xyz'. // // Next, we implemented the 'swap' method using the 'bslalg::SwapUtil::swap' to // swap the individual data elements: //.. // inline // void Container::swap(Container& other) // { // bslalg::SwapUtil::swap(&d_expensiveData, &other.d_expensiveData); // // // Equivalent to: // // using bsl::swap; // // swap(d_expensiveData, other.d_expensiveData); // } //.. // Notice that calling 'bslalg::SwapUtil::swap' is equivalent to making the // 'bsl::swap' available in the current scope by doing 'using bsl::swap' and // making a subsequent call to an unqualified 'swap' function. // // Then, we implement the 'swap' free function: //.. // inline // void swap(Container& a, Container& b) // { // a.swap(b); // } // // } // close namespace xyz //.. // Finally we can use 'bslalg::SwapUtil::swap' to swap two objects of class // 'xyz::Container': //.. // xyz::Container c1, c2; // // bslalg::SwapUtil::swap(&c1, &c2); //.. // The above code correctly calls the 'xyz::swap' overload for the 'Container' // class. #include <bslscm_version.h> #include <bsls_assert.h> #include <bsls_platform.h> #include <algorithm> namespace BloombergLP { // A workaround for GCC which before version 4.0 had some problems with ADL. #if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VER_MAJOR < 40000 class bslalg_SwapUtil_Dummy; void swap(bslalg_SwapUtil_Dummy); // Introduce 'swap' to the 'BloombergLP' namespace. The dummy argument of // a private type prevents this declaration from interfering with anything // else. #endif namespace bslalg { // =============== // struct SwapUtil // =============== class SwapUtil { // This class provides a namespace for the 'swap' utility method. public: // CLASS METHODS template <class T> static void swap(T *a, T *b); // Exchange the values of the specified 'a' and 'b' objects using // either a 'swap' free function overloaded for type 'T', in the // namespace of type 'T' if it's available, and the default generic // 'bsl::swap' otherwise. }; // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // --------------- // struct SwapUtil // --------------- // CLASS METHODS template <class T> void SwapUtil::swap(T *a, T *b) { BSLS_ASSERT_SAFE(a != NULL); BSLS_ASSERT_SAFE(b != NULL); using std::swap; // A workaround for GCC, which had some problems with ADL before version 4.0. #if defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VER_MAJOR < 40000 using BloombergLP::swap; #endif swap(*a, *b); } } // close package namespace #ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY // ============================================================================ // BACKWARD COMPATIBILITY // ============================================================================ typedef bslalg::SwapUtil bslalg_SwapUtil; // This alias is defined for backward compatibility. #endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2013 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 ----------------------------------