|
17 | 17 | namespace boost { |
18 | 18 | namespace container { |
19 | 19 |
|
20 | | -//! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed |
21 | | -//! with an allocator as its last constructor argument. Ideally, all constructors of T (including the |
22 | | -//! copy and move constructors) should have a variant that accepts a final argument of |
23 | | -//! allocator_type. |
24 | | -//! |
25 | | -//! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type, |
26 | | -//! allocator_type and at least one constructor for which allocator_type is the last |
27 | | -//! parameter. If not all constructors of T can be called with a final allocator_type argument, |
28 | | -//! and if T is used in a context where a container must call such a constructor, then the program is |
29 | | -//! ill-formed. |
30 | | -//! |
31 | | -//! <code> |
32 | | -//! template <class T, class Allocator = allocator<T> > |
33 | | -//! class Z { |
34 | | -//! public: |
35 | | -//! typedef Allocator allocator_type; |
36 | | -//! |
37 | | -//! // Default constructor with optional allocator suffix |
38 | | -//! Z(const allocator_type& a = allocator_type()); |
39 | | -//! |
40 | | -//! // Copy constructor and allocator-extended copy constructor |
41 | | -//! Z(const Z& zz); |
42 | | -//! Z(const Z& zz, const allocator_type& a); |
43 | | -//! }; |
44 | | -//! |
45 | | -//! // Specialize trait for class template Z |
46 | | -//! template <class T, class Allocator = allocator<T> > |
47 | | -//! struct constructible_with_allocator_suffix<Z<T,Allocator> > |
48 | | -//! { static const bool value = true; }; |
49 | | -//! </code> |
50 | | -//! |
51 | | -//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)" |
52 | | -//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as |
53 | | -//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. |
54 | | -//! Applications aiming portability with several compilers should always define this trait. |
55 | | -//! |
56 | | -//! In conforming C++11 compilers or compilers supporting SFINAE expressions |
57 | | -//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used |
58 | | -//! to detect if a type should be constructed with suffix or prefix allocator arguments. |
59 | | -template <class T> |
60 | | -struct constructible_with_allocator_suffix |
61 | | -{ BOOST_STATIC_CONSTEXPR bool value = false; }; |
62 | | - |
63 | | -//! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed |
64 | | -//! with allocator_arg and T::allocator_type as its first two constructor arguments. |
65 | | -//! Ideally, all constructors of T (including the copy and move constructors) should have a variant |
66 | | -//! that accepts these two initial arguments. |
67 | | -//! |
68 | | -//! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type, |
69 | | -//! allocator_type and at least one constructor for which allocator_arg_t is the first |
70 | | -//! parameter and allocator_type is the second parameter. If not all constructors of T can be |
71 | | -//! called with these initial arguments, and if T is used in a context where a container must call such |
72 | | -//! a constructor, then the program is ill-formed. |
73 | | -//! |
74 | | -//! <code> |
75 | | -//! template <class T, class Allocator = allocator<T> > |
76 | | -//! class Y { |
77 | | -//! public: |
78 | | -//! typedef Allocator allocator_type; |
79 | | -//! |
80 | | -//! // Default constructor with and allocator-extended default constructor |
81 | | -//! Y(); |
82 | | -//! Y(allocator_arg_t, const allocator_type& a); |
83 | | -//! |
84 | | -//! // Copy constructor and allocator-extended copy constructor |
85 | | -//! Y(const Y& yy); |
86 | | -//! Y(allocator_arg_t, const allocator_type& a, const Y& yy); |
87 | | -//! |
88 | | -//! // Variadic constructor and allocator-extended variadic constructor |
89 | | -//! template<class ...Args> Y(Args&& args...); |
90 | | -//! template<class ...Args> |
91 | | -//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args); |
92 | | -//! }; |
93 | | -//! |
94 | | -//! // Specialize trait for class template Y |
95 | | -//! template <class T, class Allocator = allocator<T> > |
96 | | -//! struct constructible_with_allocator_prefix<Y<T,Allocator> > |
97 | | -//! { static const bool value = true; }; |
98 | | -//! |
99 | | -//! </code> |
100 | | -//! |
101 | | -//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" |
102 | | -//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as |
103 | | -//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments. |
104 | | -//! Applications aiming portability with several compilers should always define this trait. |
105 | | -//! |
106 | | -//! In conforming C++11 compilers or compilers supporting SFINAE expressions |
107 | | -//! (when BOOST_NO_SFINAE_EXPR is NOT defined), this trait is ignored and C++11 rules will be used |
108 | | -//! to detect if a type should be constructed with suffix or prefix allocator arguments. |
109 | | -template <class T> |
110 | | -struct constructible_with_allocator_prefix |
111 | | -{ BOOST_STATIC_CONSTEXPR bool value = false; }; |
112 | | - |
113 | 20 | #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
114 | 21 |
|
115 | 22 | namespace dtl { |
@@ -147,18 +54,26 @@ struct uses_allocator_imp |
147 | 54 |
|
148 | 55 | } //namespace dtl { |
149 | 56 |
|
| 57 | +template <class T> |
| 58 | +struct constructible_with_allocator_prefix |
| 59 | +{ BOOST_STATIC_CONSTEXPR bool value = false; }; |
| 60 | + |
| 61 | +template <class T> |
| 62 | +struct constructible_with_allocator_suffix |
| 63 | +{ BOOST_STATIC_CONSTEXPR bool value = false; }; |
| 64 | + |
150 | 65 | #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED |
151 | 66 |
|
152 | 67 | //! <b>Remark</b>: Automatically detects whether T has a nested allocator_type that is convertible from |
153 | 68 | //! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may |
154 | | -//! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not |
| 69 | +//! specialize this type to define `uses_allocator<X>::value` as true for a T of user-defined type if T does not |
155 | 70 | //! have a nested allocator_type but is nonetheless constructible using the specified Allocator where either: |
156 | | -//! the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or |
157 | | -//! the last argument of a constructor has type Alloc. |
| 71 | +//! the first argument of a constructor has type `allocator_arg_t` and the second argument has type `Allocator` or |
| 72 | +//! the last argument of a constructor has type `Allocator`. |
158 | 73 | //! |
159 | | -//! <b>Result</b>: uses_allocator<T, Allocator>::value== true if a type T::allocator_type |
160 | | -//! exists and either is_convertible<Alloc, T::allocator_type>::value != false or T::allocator_type |
161 | | -//! is an alias `erased_type`. False otherwise. |
| 74 | +//! <b>Result</b>: `uses_allocator<T, Allocator>::value == true` if a type `T::allocator_type` |
| 75 | +//! exists and either `is_convertible<Allocator, T::allocator_type>::value != false` or `T::allocator_type` |
| 76 | +//! is an alias of `erased_type`. False otherwise. |
162 | 77 | template <typename T, typename Allocator> |
163 | 78 | struct uses_allocator |
164 | 79 | : dtl::uses_allocator_imp<T, Allocator> |
|
0 commit comments