Index: libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp =================================================================== --- libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp +++ libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projected.compile.pass.cpp @@ -23,6 +23,27 @@ static_assert(std::same_as()), int const&>); static_assert(std::same_as, std::ptrdiff_t>); +void test() { + { + auto projection = [](int x) { return x + 1; }; + using P = std::projected; + static_assert(std::same_as, int>); + static_assert(std::same_as, int>); + static_assert(std::same_as, std::ptrdiff_t>); + static_assert(std::same_as, int>); + static_assert(std::same_as, int>); + } + { + auto projection = [](int& x) -> int& { return x; }; + using P = std::projected; + static_assert(std::same_as, int>); + static_assert(std::same_as, int&>); + static_assert(std::same_as, std::ptrdiff_t>); + static_assert(std::same_as, int&&>); + static_assert(std::same_as, int&>); + } +} + struct S { }; using Cpp17InputIterator = std::projected, int S::*>; Index: libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projectedtest.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/iterators/iterator.requirements/indirectcallable/projected/projectedtest.compile.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts + +// projected + +#include + +#include +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __min { +struct __fn { + template > _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr + const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { + return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __a : __b; + } + + template > _Comp = ranges::less> + _LIBCPP_HIDE_FROM_ABI constexpr + _Tp operator()(initializer_list<_Tp> __r, _Comp __comp = {}, _Proj __proj = {}) const { + return *ranges::__min_element::__fn::__go(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } + + template , _Proj>> _Comp = ranges::less> + requires indirectly_copyable_storable, range_value_t<_Rp>*> + _LIBCPP_HIDE_FROM_ABI constexpr + range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + return *ranges::__min_element::__fn::__go(ranges::begin(__r), ranges::end(__r), __comp, __proj); + } +}; +} // namespace __min + +inline namespace __cpo { + inline constexpr auto min = __min::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + + +void test() { + { + auto proj = [](int i) { return i == 5 ? -100 : i; }; + int ret = std::ranges::min({7, 6, 9, 3, 5, 1, 2, 4}, std::ranges::less{}, proj); + assert(ret == 5); + } +} +