Browse Source
[common] remove ranges polyfill (#2546)
[common] remove ranges polyfill (#2546)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2546 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>pull/2567/head
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
38 changed files with 79 additions and 567 deletions
-
5src/audio_core/audio_event.cpp
-
2src/audio_core/common/feature_support.h
-
2src/audio_core/renderer/command/effect/i3dl2_reverb.cpp
-
2src/audio_core/renderer/command/effect/reverb.cpp
-
2src/audio_core/renderer/mix/mix_context.cpp
-
5src/audio_core/renderer/voice/voice_context.cpp
-
5src/common/fs/fs_util.cpp
-
530src/common/polyfill_ranges.h
-
2src/common/slot_vector.h
-
2src/core/file_sys/content_archive.cpp
-
5src/core/hle/kernel/k_thread_local_page.h
-
2src/core/hle/service/acc/acc.cpp
-
2src/core/hle/service/acc/profile_manager.cpp
-
2src/core/internal_network/network_interface.cpp
-
2src/hid_core/frontend/emulated_controller.cpp
-
5src/input_common/drivers/joycon.cpp
-
5src/shader_recompiler/frontend/ir/opcodes.h
-
5src/shader_recompiler/frontend/maxwell/control_flow.cpp
-
2src/shader_recompiler/frontend/maxwell/decode.cpp
-
5src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
-
2src/video_core/engines/maxwell_dma.cpp
-
5src/video_core/renderer_opengl/gl_device.cpp
-
5src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
-
5src/video_core/renderer_vulkan/present/smaa.cpp
-
2src/video_core/renderer_vulkan/present/util.cpp
-
2src/video_core/renderer_vulkan/renderer_vulkan.cpp
-
5src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
-
2src/video_core/renderer_vulkan/vk_master_semaphore.cpp
-
2src/video_core/renderer_vulkan/vk_swapchain.cpp
-
5src/video_core/shader_cache.h
-
2src/video_core/shader_environment.cpp
-
2src/video_core/texture_cache/formatter.cpp
-
2src/video_core/texture_cache/texture_cache_base.h
-
2src/video_core/textures/astc.cpp
-
2src/video_core/transform_feedback.cpp
-
2src/video_core/vulkan_common/vulkan_device.cpp
-
5src/video_core/vulkan_common/vulkan_instance.cpp
-
2src/video_core/vulkan_common/vulkan_memory_allocator.cpp
@ -1,530 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: 2022 yuzu Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
|
|
||||
// |
|
||||
// TODO: remove this file when ranges are supported by all compilation targets |
|
||||
// |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
#include <algorithm> |
|
||||
#include <utility> |
|
||||
#include <version> |
|
||||
|
|
||||
#ifndef __cpp_lib_ranges |
|
||||
|
|
||||
namespace std { |
|
||||
namespace ranges { |
|
||||
|
|
||||
template <typename T> |
|
||||
concept range = requires(T& t) { |
|
||||
begin(t); |
|
||||
end(t); |
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
concept input_range = range<T>; |
|
||||
|
|
||||
template <typename T> |
|
||||
concept output_range = range<T>; |
|
||||
|
|
||||
template <range R> |
|
||||
using range_difference_t = ptrdiff_t; |
|
||||
|
|
||||
// |
|
||||
// find, find_if, find_if_not |
|
||||
// |
|
||||
|
|
||||
struct find_fn { |
|
||||
template <typename Iterator, typename T, typename Proj = std::identity> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, const T& value, |
|
||||
Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (std::invoke(proj, *first) == value) { |
|
||||
return first; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T, typename Proj = std::identity> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, const T& value, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), value, std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct find_if_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (std::invoke(pred, std::invoke(proj, *first))) { |
|
||||
return first; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct find_if_not_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (!std::invoke(pred, std::invoke(proj, *first))) { |
|
||||
return first; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr find_fn find; |
|
||||
inline constexpr find_if_fn find_if; |
|
||||
inline constexpr find_if_not_fn find_if_not; |
|
||||
|
|
||||
// |
|
||||
// any_of, all_of, none_of |
|
||||
// |
|
||||
|
|
||||
struct all_of_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
return ranges::find_if_not(first, last, std::ref(pred), std::ref(proj)) == last; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct any_of_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
return ranges::find_if(first, last, std::ref(pred), std::ref(proj)) != last; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct none_of_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
return ranges::find_if(first, last, std::ref(pred), std::ref(proj)) == last; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr bool operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr any_of_fn any_of; |
|
||||
inline constexpr all_of_fn all_of; |
|
||||
inline constexpr none_of_fn none_of; |
|
||||
|
|
||||
// |
|
||||
// count, count_if |
|
||||
// |
|
||||
|
|
||||
struct count_fn { |
|
||||
template <typename Iterator, typename T, typename Proj = std::identity> |
|
||||
constexpr ptrdiff_t operator()(Iterator first, Iterator last, const T& value, |
|
||||
Proj proj = {}) const { |
|
||||
ptrdiff_t counter = 0; |
|
||||
for (; first != last; ++first) |
|
||||
if (std::invoke(proj, *first) == value) |
|
||||
++counter; |
|
||||
return counter; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T, typename Proj = std::identity> |
|
||||
constexpr ptrdiff_t operator()(R&& r, const T& value, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), value, std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct count_if_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred> |
|
||||
constexpr ptrdiff_t operator()(Iterator first, Iterator last, Pred pred, Proj proj = {}) const { |
|
||||
ptrdiff_t counter = 0; |
|
||||
for (; first != last; ++first) |
|
||||
if (std::invoke(pred, std::invoke(proj, *first))) |
|
||||
++counter; |
|
||||
return counter; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Pred> |
|
||||
constexpr ptrdiff_t operator()(R&& r, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr count_fn count; |
|
||||
inline constexpr count_if_fn count_if; |
|
||||
|
|
||||
// |
|
||||
// transform |
|
||||
// |
|
||||
|
|
||||
struct transform_fn { |
|
||||
template <typename InputIterator, typename OutputIterator, typename F, |
|
||||
typename Proj = std::identity> |
|
||||
constexpr void operator()(InputIterator first1, InputIterator last1, OutputIterator result, |
|
||||
F op, Proj proj = {}) const { |
|
||||
for (; first1 != last1; ++first1, (void)++result) { |
|
||||
*result = std::invoke(op, std::invoke(proj, *first1)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename OutputIterator, typename F, |
|
||||
typename Proj = std::identity> |
|
||||
constexpr void operator()(R&& r, OutputIterator result, F op, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), result, std::ref(op), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr transform_fn transform; |
|
||||
|
|
||||
// |
|
||||
// sort |
|
||||
// |
|
||||
|
|
||||
struct sort_fn { |
|
||||
template <typename Iterator, typename Comp = ranges::less, typename Proj = std::identity> |
|
||||
constexpr void operator()(Iterator first, Iterator last, Comp comp = {}, Proj proj = {}) const { |
|
||||
if (first == last) |
|
||||
return; |
|
||||
|
|
||||
Iterator last_iter = ranges::next(first, last); |
|
||||
std::sort(first, last_iter, |
|
||||
[&](auto& lhs, auto& rhs) { return comp(proj(lhs), proj(rhs)); }); |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Comp = ranges::less, typename Proj = std::identity> |
|
||||
constexpr void operator()(R&& r, Comp comp = {}, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(comp), std::move(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr sort_fn sort; |
|
||||
|
|
||||
// |
|
||||
// fill |
|
||||
// |
|
||||
|
|
||||
struct fill_fn { |
|
||||
template <typename T, typename OutputIterator> |
|
||||
constexpr OutputIterator operator()(OutputIterator first, OutputIterator last, |
|
||||
const T& value) const { |
|
||||
while (first != last) { |
|
||||
*first++ = value; |
|
||||
} |
|
||||
|
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <typename T, ranges::output_range R> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, const T& value) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), value); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr fill_fn fill; |
|
||||
|
|
||||
// |
|
||||
// for_each |
|
||||
// |
|
||||
|
|
||||
struct for_each_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Fun> |
|
||||
constexpr void operator()(Iterator first, Iterator last, Fun f, Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
std::invoke(f, std::invoke(proj, *first)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Fun> |
|
||||
constexpr void operator()(R&& r, Fun f, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(f), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr for_each_fn for_each; |
|
||||
|
|
||||
// |
|
||||
// min_element, max_element |
|
||||
// |
|
||||
|
|
||||
struct min_element_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Comp = ranges::less> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
if (first == last) { |
|
||||
return last; |
|
||||
} |
|
||||
|
|
||||
auto smallest = first; |
|
||||
++first; |
|
||||
for (; first != last; ++first) { |
|
||||
if (!std::invoke(comp, std::invoke(proj, *smallest), std::invoke(proj, *first))) { |
|
||||
smallest = first; |
|
||||
} |
|
||||
} |
|
||||
return smallest; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Comp = ranges::less> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(comp), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct max_element_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Comp = ranges::less> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
if (first == last) { |
|
||||
return last; |
|
||||
} |
|
||||
|
|
||||
auto largest = first; |
|
||||
++first; |
|
||||
for (; first != last; ++first) { |
|
||||
if (std::invoke(comp, std::invoke(proj, *largest), std::invoke(proj, *first))) { |
|
||||
largest = first; |
|
||||
} |
|
||||
} |
|
||||
return largest; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, typename Comp = ranges::less> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Comp comp = {}, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(comp), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr min_element_fn min_element; |
|
||||
inline constexpr max_element_fn max_element; |
|
||||
|
|
||||
// |
|
||||
// replace, replace_if |
|
||||
// |
|
||||
|
|
||||
struct replace_fn { |
|
||||
template <typename Iterator, typename T1, typename T2, typename Proj = std::identity> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, const T1& old_value, |
|
||||
const T2& new_value, Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (old_value == std::invoke(proj, *first)) { |
|
||||
*first = new_value; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T1, typename T2, typename Proj = std::identity> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, const T1& old_value, const T2& new_value, |
|
||||
Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), old_value, new_value, std::move(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct replace_if_fn { |
|
||||
template <typename Iterator, typename T, typename Proj = std::identity, typename Pred> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Pred pred, const T& new_value, |
|
||||
Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (!!std::invoke(pred, std::invoke(proj, *first))) { |
|
||||
*first = new_value; |
|
||||
} |
|
||||
} |
|
||||
return std::move(first); |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T, typename Proj = std::identity, typename Pred> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Pred pred, const T& new_value, |
|
||||
Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(pred), new_value, |
|
||||
std::move(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr replace_fn replace; |
|
||||
inline constexpr replace_if_fn replace_if; |
|
||||
|
|
||||
// |
|
||||
// copy, copy_if |
|
||||
// |
|
||||
|
|
||||
struct copy_fn { |
|
||||
template <typename InputIterator, typename OutputIterator> |
|
||||
constexpr void operator()(InputIterator first, InputIterator last, |
|
||||
OutputIterator result) const { |
|
||||
for (; first != last; ++first, (void)++result) { |
|
||||
*result = *first; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename OutputIterator> |
|
||||
constexpr void operator()(R&& r, OutputIterator result) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(result)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct copy_if_fn { |
|
||||
template <typename InputIterator, typename OutputIterator, typename Proj = std::identity, |
|
||||
typename Pred> |
|
||||
constexpr void operator()(InputIterator first, InputIterator last, OutputIterator result, |
|
||||
Pred pred, Proj proj = {}) const { |
|
||||
for (; first != last; ++first) { |
|
||||
if (std::invoke(pred, std::invoke(proj, *first))) { |
|
||||
*result = *first; |
|
||||
++result; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename OutputIterator, typename Proj = std::identity, |
|
||||
typename Pred> |
|
||||
constexpr void operator()(R&& r, OutputIterator result, Pred pred, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(result), std::ref(pred), |
|
||||
std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr copy_fn copy; |
|
||||
inline constexpr copy_if_fn copy_if; |
|
||||
|
|
||||
// |
|
||||
// generate |
|
||||
// |
|
||||
|
|
||||
struct generate_fn { |
|
||||
template <typename Iterator, typename F> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, F gen) const { |
|
||||
for (; first != last; *first = std::invoke(gen), ++first) |
|
||||
; |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <typename R, std::copy_constructible F> |
|
||||
requires std::invocable<F&> && ranges::output_range<R> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::move(gen)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr generate_fn generate; |
|
||||
|
|
||||
// |
|
||||
// lower_bound, upper_bound |
|
||||
// |
|
||||
|
|
||||
struct lower_bound_fn { |
|
||||
template <typename Iterator, typename T, typename Proj = std::identity, |
|
||||
typename Comp = ranges::less> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, const T& value, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
Iterator it; |
|
||||
std::ptrdiff_t _count, _step; |
|
||||
_count = std::distance(first, last); |
|
||||
|
|
||||
while (_count > 0) { |
|
||||
it = first; |
|
||||
_step = _count / 2; |
|
||||
ranges::advance(it, _step, last); |
|
||||
if (comp(std::invoke(proj, *it), value)) { |
|
||||
first = ++it; |
|
||||
_count -= _step + 1; |
|
||||
} else { |
|
||||
_count = _step; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T, typename Proj = std::identity, |
|
||||
typename Comp = ranges::less> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, const T& value, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), value, std::ref(comp), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
struct upper_bound_fn { |
|
||||
template <typename Iterator, typename T, typename Proj = std::identity, |
|
||||
typename Comp = ranges::less> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, const T& value, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
Iterator it; |
|
||||
std::ptrdiff_t _count, _step; |
|
||||
_count = std::distance(first, last); |
|
||||
|
|
||||
while (_count > 0) { |
|
||||
it = first; |
|
||||
_step = _count / 2; |
|
||||
ranges::advance(it, _step, last); |
|
||||
if (!comp(value, std::invoke(proj, *it))) { |
|
||||
first = ++it; |
|
||||
_count -= _step + 1; |
|
||||
} else { |
|
||||
_count = _step; |
|
||||
} |
|
||||
} |
|
||||
return first; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename T, typename Proj = std::identity, |
|
||||
typename Comp = ranges::less> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, const T& value, Comp comp = {}, |
|
||||
Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), value, std::ref(comp), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr lower_bound_fn lower_bound; |
|
||||
inline constexpr upper_bound_fn upper_bound; |
|
||||
|
|
||||
// |
|
||||
// adjacent_find |
|
||||
// |
|
||||
|
|
||||
struct adjacent_find_fn { |
|
||||
template <typename Iterator, typename Proj = std::identity, typename Pred = ranges::equal_to> |
|
||||
constexpr Iterator operator()(Iterator first, Iterator last, Pred pred = {}, |
|
||||
Proj proj = {}) const { |
|
||||
if (first == last) |
|
||||
return first; |
|
||||
auto _next = ranges::next(first); |
|
||||
for (; _next != last; ++_next, ++first) |
|
||||
if (std::invoke(pred, std::invoke(proj, *first), std::invoke(proj, *_next))) |
|
||||
return first; |
|
||||
return _next; |
|
||||
} |
|
||||
|
|
||||
template <ranges::input_range R, typename Proj = std::identity, |
|
||||
typename Pred = ranges::equal_to> |
|
||||
constexpr ranges::iterator_t<R> operator()(R&& r, Pred pred = {}, Proj proj = {}) const { |
|
||||
return operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
inline constexpr adjacent_find_fn adjacent_find; |
|
||||
|
|
||||
} // namespace ranges |
|
||||
} // namespace std |
|
||||
|
|
||||
#endif |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue