|
||||
File indexing completed on 2025-01-30 09:35:05
0001 ////////////////////////////////////////////////////////////////////////////// 0002 // 0003 // (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost 0004 // Software License, Version 1.0. (See accompanying file 0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // See http://www.boost.org/libs/container for documentation. 0008 // 0009 ////////////////////////////////////////////////////////////////////////////// 0010 0011 #ifndef BOOST_CONTAINER_USES_ALLOCATOR_HPP 0012 #define BOOST_CONTAINER_USES_ALLOCATOR_HPP 0013 0014 #include <boost/container/uses_allocator_fwd.hpp> 0015 #include <boost/container/detail/type_traits.hpp> 0016 0017 namespace boost { 0018 namespace container { 0019 0020 //! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed 0021 //! with an allocator as its last constructor argument. Ideally, all constructors of T (including the 0022 //! copy and move constructors) should have a variant that accepts a final argument of 0023 //! allocator_type. 0024 //! 0025 //! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type, 0026 //! allocator_type and at least one constructor for which allocator_type is the last 0027 //! parameter. If not all constructors of T can be called with a final allocator_type argument, 0028 //! and if T is used in a context where a container must call such a constructor, then the program is 0029 //! ill-formed. 0030 //! 0031 //! <code> 0032 //! template <class T, class Allocator = allocator<T> > 0033 //! class Z { 0034 //! public: 0035 //! typedef Allocator allocator_type; 0036 //! 0037 //! // Default constructor with optional allocator suffix 0038 //! Z(const allocator_type& a = allocator_type()); 0039 //! 0040 //! // Copy constructor and allocator-extended copy constructor 0041 //! Z(const Z& zz); 0042 //! Z(const Z& zz, const allocator_type& a); 0043 //! }; 0044 //! 0045 //! // Specialize trait for class template Z 0046 //! template <class T, class Allocator = allocator<T> > 0047 //! struct constructible_with_allocator_suffix<Z<T,Allocator> > 0048 //! { static const bool value = true; }; 0049 //! </code> 0050 //! 0051 //! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)" 0052 //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as 0053 //! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. 0054 //! Applications aiming portability with several compilers should always define this trait. 0055 //! 0056 //! In conforming C++11 compilers or compilers supporting SFINAE expressions 0057 //! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used 0058 //! to detect if a type should be constructed with suffix or prefix allocator arguments. 0059 template <class T> 0060 struct constructible_with_allocator_suffix 0061 { static const bool value = false; }; 0062 0063 //! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed 0064 //! with allocator_arg and T::allocator_type as its first two constructor arguments. 0065 //! Ideally, all constructors of T (including the copy and move constructors) should have a variant 0066 //! that accepts these two initial arguments. 0067 //! 0068 //! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type, 0069 //! allocator_type and at least one constructor for which allocator_arg_t is the first 0070 //! parameter and allocator_type is the second parameter. If not all constructors of T can be 0071 //! called with these initial arguments, and if T is used in a context where a container must call such 0072 //! a constructor, then the program is ill-formed. 0073 //! 0074 //! <code> 0075 //! template <class T, class Allocator = allocator<T> > 0076 //! class Y { 0077 //! public: 0078 //! typedef Allocator allocator_type; 0079 //! 0080 //! // Default constructor with and allocator-extended default constructor 0081 //! Y(); 0082 //! Y(allocator_arg_t, const allocator_type& a); 0083 //! 0084 //! // Copy constructor and allocator-extended copy constructor 0085 //! Y(const Y& yy); 0086 //! Y(allocator_arg_t, const allocator_type& a, const Y& yy); 0087 //! 0088 //! // Variadic constructor and allocator-extended variadic constructor 0089 //! template<class ...Args> Y(Args&& args...); 0090 //! template<class ...Args> 0091 //! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args); 0092 //! }; 0093 //! 0094 //! // Specialize trait for class template Y 0095 //! template <class T, class Allocator = allocator<T> > 0096 //! struct constructible_with_allocator_prefix<Y<T,Allocator> > 0097 //! { static const bool value = true; }; 0098 //! 0099 //! </code> 0100 //! 0101 //! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" 0102 //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as 0103 //! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. 0104 //! Applications aiming portability with several compilers should always define this trait. 0105 //! 0106 //! In conforming C++11 compilers or compilers supporting SFINAE expressions 0107 //! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used 0108 //! to detect if a type should be constructed with suffix or prefix allocator arguments. 0109 template <class T> 0110 struct constructible_with_allocator_prefix 0111 { static const bool value = false; }; 0112 0113 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0114 0115 namespace dtl { 0116 0117 template<typename T, typename Allocator> 0118 struct uses_allocator_imp 0119 { 0120 // Use SFINAE (Substitution Failure Is Not An Error) to detect the 0121 // presence of an 'allocator_type' nested type convertilble from Allocator. 0122 private: 0123 typedef char yes_type; 0124 struct no_type{ char dummy[2]; }; 0125 0126 // Match this function if T::allocator_type exists and is 0127 // implicitly convertible from Allocator 0128 template <class U> 0129 static yes_type test(typename U::allocator_type); 0130 0131 // Match this function if T::allocator_type exists and it's type is `erased_type`. 0132 template <class U, class V> 0133 static typename dtl::enable_if 0134 < dtl::is_same<typename U::allocator_type, erased_type> 0135 , yes_type 0136 >::type test(const V&); 0137 0138 // Match this function if TypeT::allocator_type does not exist or is 0139 // not convertible from Allocator. 0140 template <typename U> 0141 static no_type test(...); 0142 static Allocator alloc; // Declared but not defined 0143 0144 public: 0145 static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type); 0146 }; 0147 0148 } //namespace dtl { 0149 0150 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED 0151 0152 //! <b>Remark</b>: Automatically detects whether T has a nested allocator_type that is convertible from 0153 //! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may 0154 //! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not 0155 //! have a nested allocator_type but is nonetheless constructible using the specified Allocator where either: 0156 //! the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or 0157 //! the last argument of a constructor has type Alloc. 0158 //! 0159 //! <b>Result</b>: uses_allocator<T, Allocator>::value== true if a type T::allocator_type 0160 //! exists and either is_convertible<Alloc, T::allocator_type>::value != false or T::allocator_type 0161 //! is an alias `erased_type`. False otherwise. 0162 template <typename T, typename Allocator> 0163 struct uses_allocator 0164 : dtl::uses_allocator_imp<T, Allocator> 0165 {}; 0166 0167 }} //namespace boost::container 0168 0169 #endif //BOOST_CONTAINER_USES_ALLOCATOR_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |