|
18 | 18 |
|
19 | 19 | namespace boost { |
20 | 20 | namespace buffers { |
21 | | -namespace detail { |
22 | 21 |
|
23 | | -struct begin_impl |
| 22 | +/** Return an iterator to the beginning of the buffer sequence. |
| 23 | +*/ |
| 24 | +constexpr struct |
24 | 25 | { |
25 | | - template<class MutableBuffer> |
26 | | - auto |
27 | | - operator()( |
28 | | - MutableBuffer const& b) const noexcept -> |
29 | | - typename std::enable_if< |
30 | | - std::is_convertible< |
31 | | - MutableBuffer const*, |
32 | | - mutable_buffer const*>::value, |
33 | | - mutable_buffer const*>::type |
| 26 | + // mutable_buffer is a sequence of length 1 |
| 27 | + template<class T> |
| 28 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 29 | + std::is_convertible<T const*, mutable_buffer const*>::value, |
| 30 | + mutable_buffer const*>::type |
34 | 31 | { |
35 | | - return static_cast< |
36 | | - mutable_buffer const*>( |
37 | | - std::addressof(b)); |
| 32 | + return static_cast<mutable_buffer const*>(std::addressof(t)); |
38 | 33 | } |
39 | 34 |
|
40 | | - template<class ConstBuffer> |
41 | | - auto |
42 | | - operator()( |
43 | | - ConstBuffer const& b) const noexcept -> |
44 | | - typename std::enable_if< |
45 | | - std::is_convertible< |
46 | | - ConstBuffer const*, |
47 | | - const_buffer const*>::value, |
48 | | - const_buffer const*>::type |
| 35 | + // const_buffer is a sequence of length 1 |
| 36 | + template<class T> |
| 37 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 38 | + std::is_convertible<T const*, const_buffer const*>::value, |
| 39 | + const_buffer const*>::type |
49 | 40 | { |
50 | | - return static_cast< |
51 | | - const_buffer const*>( |
52 | | - std::addressof(b)); |
| 41 | + return static_cast<const_buffer const*>(std::addressof(t)); |
53 | 42 | } |
54 | 43 |
|
55 | | - template<class BufferSequence> |
56 | | - auto |
57 | | - operator()( |
58 | | - BufferSequence& bs) const noexcept -> |
59 | | - typename std::enable_if< |
60 | | - ! std::is_convertible< |
61 | | - BufferSequence const*, |
62 | | - const_buffer const*>::value && |
63 | | - ! std::is_convertible< |
64 | | - BufferSequence const*, |
65 | | - mutable_buffer const*>::value, |
66 | | - decltype(bs.begin())>::type |
| 44 | + // Convertible T is a sequence of length 1 |
| 45 | + template<class T> |
| 46 | + auto operator()(T const& t) const noexcept -> |
| 47 | + typename std::enable_if< |
| 48 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 49 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && ( |
| 50 | + std::is_convertible<T, const_buffer>::value || |
| 51 | + std::is_convertible<T, mutable_buffer>::value) |
| 52 | + >::type |
67 | 53 | { |
68 | | - return bs.begin(); |
| 54 | + return std::addressof(t); |
69 | 55 | } |
70 | 56 |
|
71 | | - template<class BufferSequence> |
72 | | - auto |
73 | | - operator()( |
74 | | - BufferSequence const& bs) const noexcept -> |
75 | | - typename std::enable_if< |
76 | | - ! std::is_convertible< |
77 | | - BufferSequence const*, |
78 | | - const_buffer const*>::value && |
79 | | - ! std::is_convertible< |
80 | | - BufferSequence const*, |
81 | | - mutable_buffer const*>::value, |
82 | | - decltype(bs.begin())>::type |
| 57 | + // Bidirectional range with convertible value type |
| 58 | + template<class T> |
| 59 | + auto operator()(T& t) const noexcept -> typename std::enable_if< |
| 60 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 61 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && |
| 62 | + ! std::is_convertible<T, const_buffer>::value && |
| 63 | + ! std::is_convertible<T, mutable_buffer>::value, |
| 64 | + decltype(t.begin())>::type |
83 | 65 | { |
84 | | - return bs.begin(); |
| 66 | + return t.begin(); |
85 | 67 | } |
86 | | -}; |
87 | 68 |
|
88 | | -struct end_impl |
89 | | -{ |
90 | | - template<class MutableBuffer> |
91 | | - auto |
92 | | - operator()( |
93 | | - MutableBuffer const& b) const noexcept -> |
94 | | - typename std::enable_if< |
95 | | - std::is_convertible< |
96 | | - MutableBuffer const*, |
97 | | - mutable_buffer const*>::value, |
98 | | - mutable_buffer const*>::type |
| 69 | + // Bidirectional range with convertible value type |
| 70 | + template<class T> |
| 71 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 72 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 73 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && |
| 74 | + ! std::is_convertible<T, const_buffer>::value && |
| 75 | + ! std::is_convertible<T, mutable_buffer>::value, |
| 76 | + decltype(t.begin())>::type |
99 | 77 | { |
100 | | - return static_cast< |
101 | | - mutable_buffer const*>( |
102 | | - std::addressof(b)) + 1; |
| 78 | + return t.begin(); |
103 | 79 | } |
| 80 | +} begin {}; |
104 | 81 |
|
105 | | - template<class ConstBuffer> |
106 | | - auto |
107 | | - operator()( |
108 | | - ConstBuffer const& b) const noexcept -> |
109 | | - typename std::enable_if< |
110 | | - std::is_convertible< |
111 | | - ConstBuffer const*, |
112 | | - const_buffer const*>::value, |
113 | | - const_buffer const*>::type |
| 82 | +/** Return an iterator to the end of the buffer sequence. |
| 83 | +*/ |
| 84 | +constexpr struct |
| 85 | +{ |
| 86 | + // mutable_buffer is a sequence of length 1 |
| 87 | + template<class T> |
| 88 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 89 | + std::is_convertible<T const*, mutable_buffer const*>::value, |
| 90 | + mutable_buffer const*>::type |
114 | 91 | { |
115 | | - return static_cast< |
116 | | - const_buffer const*>( |
117 | | - std::addressof(b)) + 1; |
| 92 | + return static_cast<mutable_buffer const*>(std::addressof(t)) + 1; |
118 | 93 | } |
119 | 94 |
|
120 | | - template<class BufferSequence> |
121 | | - auto |
122 | | - operator()( |
123 | | - BufferSequence& bs) const noexcept -> |
124 | | - typename std::enable_if< |
125 | | - ! std::is_convertible< |
126 | | - BufferSequence const*, |
127 | | - const_buffer const*>::value && |
128 | | - ! std::is_convertible< |
129 | | - BufferSequence const*, |
130 | | - mutable_buffer const*>::value, |
131 | | - decltype(bs.end())>::type |
| 95 | + // const_buffer is a sequence of length 1 |
| 96 | + template<class T> |
| 97 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 98 | + std::is_convertible<T const*, const_buffer const*>::value, |
| 99 | + const_buffer const*>::type |
132 | 100 | { |
133 | | - return bs.end(); |
| 101 | + return static_cast<const_buffer const*>(std::addressof(t)) + 1; |
134 | 102 | } |
135 | 103 |
|
136 | | - template<class BufferSequence> |
137 | | - auto |
138 | | - operator()( |
139 | | - BufferSequence const& bs) const noexcept -> |
140 | | - typename std::enable_if< |
141 | | - ! std::is_convertible< |
142 | | - BufferSequence const*, |
143 | | - const_buffer const*>::value && |
144 | | - ! std::is_convertible< |
145 | | - BufferSequence const*, |
146 | | - mutable_buffer const*>::value, |
147 | | - decltype(bs.end())>::type |
| 104 | + // Convertible T is a sequence of length 1 |
| 105 | + template<class T> |
| 106 | + auto operator()(T const& t) const noexcept -> |
| 107 | + typename std::enable_if< |
| 108 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 109 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && ( |
| 110 | + std::is_convertible<T, const_buffer>::value || |
| 111 | + std::is_convertible<T, mutable_buffer>::value) |
| 112 | + >::type |
148 | 113 | { |
149 | | - return bs.end(); |
| 114 | + return std::addressof(t) + 1; |
150 | 115 | } |
151 | | -}; |
152 | 116 |
|
153 | | -} // detail |
154 | | - |
155 | | -/** Return an iterator to the beginning of the buffer sequence. |
156 | | -*/ |
157 | | -constexpr detail::begin_impl begin{}; |
| 117 | + // Bidirectional range with convertible value type |
| 118 | + template<class T> |
| 119 | + auto operator()(T& t) const noexcept -> typename std::enable_if< |
| 120 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 121 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && |
| 122 | + ! std::is_convertible<T, const_buffer>::value && |
| 123 | + ! std::is_convertible<T, mutable_buffer>::value, |
| 124 | + decltype(t.end())>::type |
| 125 | + { |
| 126 | + return t.end(); |
| 127 | + } |
158 | 128 |
|
159 | | -/** Return an iterator to the end of the buffer sequence. |
160 | | -*/ |
161 | | -constexpr detail::end_impl end{}; |
| 129 | + // Bidirectional range with convertible value type |
| 130 | + template<class T> |
| 131 | + auto operator()(T const& t) const noexcept -> typename std::enable_if< |
| 132 | + ! std::is_convertible<T const*, const_buffer const*>::value && |
| 133 | + ! std::is_convertible<T const*, mutable_buffer const*>::value && |
| 134 | + ! std::is_convertible<T, const_buffer>::value && |
| 135 | + ! std::is_convertible<T, mutable_buffer>::value, |
| 136 | + decltype(t.end())>::type |
| 137 | + { |
| 138 | + return t.end(); |
| 139 | + } |
| 140 | +} end {}; |
162 | 141 |
|
163 | 142 | //------------------------------------------------ |
164 | 143 |
|
|
0 commit comments