//===- llvm/ADT/ADL.h - Argument dependent lookup utilities -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_ADL_H #define LLVM_ADT_ADL_H #include #include #include namespace llvm { // Only used by compiler if both template types are the same. Useful when // using SFINAE to test for the existence of member functions. template struct SameType; namespace adl_detail { using std::begin; template constexpr auto begin_impl(RangeT &&range) -> decltype(begin(std::forward(range))) { return begin(std::forward(range)); } using std::end; template constexpr auto end_impl(RangeT &&range) -> decltype(end(std::forward(range))) { return end(std::forward(range)); } using std::swap; template constexpr void swap_impl(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval(), std::declval()))) { swap(std::forward(lhs), std::forward(rhs)); } using std::size; template constexpr auto size_impl(RangeT &&range) -> decltype(size(std::forward(range))) { return size(std::forward(range)); } } // end namespace adl_detail /// Returns the begin iterator to \p range using `std::begin` and /// function found through Argument-Dependent Lookup (ADL). template constexpr auto adl_begin(RangeT &&range) -> decltype(adl_detail::begin_impl(std::forward(range))) { return adl_detail::begin_impl(std::forward(range)); } /// Returns the end iterator to \p range using `std::end` and /// functions found through Argument-Dependent Lookup (ADL). template constexpr auto adl_end(RangeT &&range) -> decltype(adl_detail::end_impl(std::forward(range))) { return adl_detail::end_impl(std::forward(range)); } /// Swaps \p lhs with \p rhs using `std::swap` and functions found through /// Argument-Dependent Lookup (ADL). template constexpr void adl_swap(T &&lhs, T &&rhs) noexcept( noexcept(adl_detail::swap_impl(std::declval(), std::declval()))) { adl_detail::swap_impl(std::forward(lhs), std::forward(rhs)); } /// Returns the size of \p range using `std::size` and functions found through /// Argument-Dependent Lookup (ADL). template constexpr auto adl_size(RangeT &&range) -> decltype(adl_detail::size_impl(std::forward(range))) { return adl_detail::size_impl(std::forward(range)); } namespace detail { template using IterOfRange = decltype(adl_begin(std::declval())); template using ValueOfRange = std::remove_reference_t()))>; } // namespace detail } // namespace llvm #endif // LLVM_ADT_ADL_H