// bslmf_usesallocator.h -*-C++-*- #ifndef INCLUDED_BSLMF_USESALLOCATOR #define INCLUDED_BSLMF_USESALLOCATOR #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a meta-function to determine if a type uses an allocator. // //@CLASSES: // bsl::uses_allocator: meta-fn to check if a type uses a certain allocator // bsl::uses_allocator_v: the result value of 'bsl::uses_allocator' // //@SEE_ALSO: bslmf_isconvertible // //@DESCRIPTION: This component defines a meta-function, 'bsl::uses_allocator', // that may be used to query whether a given type uses a given allocator type. // // 'bsl::uses_allocator' meets the requirements of the 'uses_allocator' // template defined in the C++11 standard [allocator.uses.trait], in addition // to providing a welcome availability in both C++03 and C++11 compilation // environments. // // A type 'T' uses an allocator type 'A' if 'A' has a nested alias named // 'allocator_type' and 'A' is convertible to 'allocator_type' (as defined in // the 'bslmf_isconvertible' component). If a type 'T' uses an allocator type // 'A', then 'T' has a constructor that takes either 1) 'allocator_arg_t' as a // first argument and 'A' as a second argument, or 2) 'A' as the last argument. // Alternatively, the 'uses_allocator' template may be specialized for a type // 'T' that does not have a nested alias named 'allocator_type', where 'T' can // be constructed with 'A' as detailed above. // // Note that the template variable 'uses_allocator_v' is defined in the C++17 // standard as an inline variable. If the current compiler supports the inline // variable C++17 compiler feature, 'bsl::uses_allocator_v' is defined as an // 'inline constexpr bool' variable. Otherwise, if the compiler supports the // variable templates C++14 compiler feature, 'bsl::uses_allocator_v' is // defined as a non-inline 'constexpr bool' variable. See // 'BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES' and // 'BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES' macros in // bsls_compilerfeatures component for details. // ///Usage ///----- // In this section we show intended use of this component. // // TBD: finish up usage example, add to test driver. // ///Example 1: Determine If a Type Uses an Allocator ///- - - - - - - - - - - - - - - - - - - - - - - - // //.. // template <class CONTAINER> // class ContainerAdaptor { // // ... // public: // ContainerAdaptor(); // // Create an empty container adaptor. No allocator will be provided // // to the underlying container, and the container's memory // // allocation will be provided by whatever is the default for the // // container type. // // template <class t_ALLOC> // explicit // ContainerAdaptor(const t_ALLOC& basicAllocator, // typename bsl::enable_if< // bsl::uses_allocator<CONTAINER, t_ALLOC>::value, // t_ALLOC>::type * = 0); // // Create an empty container adaptor, and use the specified // // 'basicAllocator' to supply memory. Note that this constructor is // // available only when the type of the argument is compatible with // // the allocator type associated with the container. // // // ... // }; //.. // #include <bslscm_version.h> #include <bslmf_integralconstant.h> #include <bslmf_isconvertible.h> #include <bslmf_voidtype.h> #include <bsls_compilerfeatures.h> #include <bsls_keyword.h> namespace BloombergLP { namespace bslmf { template <class t_TYPE, class t_ALLOC, class = void> struct UsesAllocator_Imp : bsl::false_type { // This 'struct' template derives from 'bsl::false_type' when the (template // parameter) type 't_TYPE' does not have a nested alias 'allocator_type'. }; template <class t_TYPE, class t_ALLOC> struct UsesAllocator_Imp<t_TYPE, t_ALLOC, BSLMF_VOIDTYPE(typename t_TYPE::allocator_type)> : bsl::is_convertible<t_ALLOC, typename t_TYPE::allocator_type>::type { // This 'struct' template derives from 'bsl::true_type' when the (template // parameter) 't_TYPE' has a nested alias 'allocator_type' and the // (template parameter) type 't_ALLOC' is convertible to // 't_TYPE::allocator_type', and 'bsl::false_type' otherwise. }; } // close package namespace } // close enterprise namespace namespace bsl { // ===================== // struct uses_allocator // ===================== template <class t_TYPE, class t_ALLOCATOR_TYPE> struct uses_allocator : BloombergLP::bslmf::UsesAllocator_Imp<t_TYPE, t_ALLOCATOR_TYPE>::type { // This 'struct' template implements a meta-function to determine whether a // (template parameter) 't_TYPE' uses a given (template parameter) // 't_ALLOCATOR_TYPE'. This 'struct' derives from 'bsl::true_type' if // 't_TYPE' uses 't_ALLOCATOR_TYPE' and from 'bsl::false_type' otherwise. // This meta-function has the same syntax as the 'uses_allocator' // meta-function defined in the C++11 standard [allocator.uses.trait]. }; #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES template <class t_TYPE, class t_ALLOCATOR_TYPE> BSLS_KEYWORD_INLINE_VARIABLE constexpr bool uses_allocator_v = uses_allocator<t_TYPE, t_ALLOCATOR_TYPE>::value; // This template variable represents the result value of the // 'bsl::uses_allocator' meta-function. #endif } // close namespace bsl #endif // ---------------------------------------------------------------------------- // Copyright 2019 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 ----------------------------------