| 186 | }; |
| 187 | |
| 188 | struct impl |
| 189 | { |
| 190 | template <typename T> |
| 191 | struct proxy |
| 192 | { |
| 193 | #if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
| 194 | struct type |
| 195 | { |
| 196 | template <typename P> |
| 197 | auto query(ASIO_MOVE_ARG(P) p) |
| 198 | noexcept( |
| 199 | noexcept( |
| 200 | declval<typename conditional<true, T, P>::type>().query( |
| 201 | ASIO_MOVE_CAST(P)(p)) |
| 202 | ) |
| 203 | ) |
| 204 | -> decltype( |
| 205 | declval<typename conditional<true, T, P>::type>().query( |
| 206 | ASIO_MOVE_CAST(P)(p)) |
| 207 | ); |
| 208 | }; |
| 209 | #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
| 210 | typedef T type; |
| 211 | #endif // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) |
| 212 | }; |
| 213 | |
| 214 | template <typename T, typename Property> |
| 215 | ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< |
| 216 | call_traits<impl, T, void(Property)>::overload == static_value, |
| 217 | typename call_traits<impl, T, void(Property)>::result_type |
| 218 | >::type |
| 219 | operator()( |
| 220 | ASIO_MOVE_ARG(T), |
| 221 | ASIO_MOVE_ARG(Property)) const |
| 222 | ASIO_NOEXCEPT_IF(( |
| 223 | call_traits<impl, T, void(Property)>::is_noexcept)) |
| 224 | { |
| 225 | return static_query< |
| 226 | typename decay<T>::type, |
| 227 | typename decay<Property>::type |
| 228 | >::value(); |
| 229 | } |
| 230 | |
| 231 | template <typename T, typename Property> |
| 232 | ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< |
| 233 | call_traits<impl, T, void(Property)>::overload == call_member, |
| 234 | typename call_traits<impl, T, void(Property)>::result_type |
| 235 | >::type |
| 236 | operator()( |
| 237 | ASIO_MOVE_ARG(T) t, |
| 238 | ASIO_MOVE_ARG(Property) p) const |
| 239 | ASIO_NOEXCEPT_IF(( |
| 240 | call_traits<impl, T, void(Property)>::is_noexcept)) |
| 241 | { |
| 242 | return ASIO_MOVE_CAST(T)(t).query(ASIO_MOVE_CAST(Property)(p)); |
| 243 | } |
| 244 | |
| 245 | template <typename T, typename Property> |