12 auto operator()(T& value)
const noexcept ->
decltype(value.first)& {
19 auto operator()(T& value)
const noexcept ->
decltype(value.second)& {
24template <
class BaseIterator,
class Projection>
25class ProjectingIterator : Projection {
27 using iterator_category = std::forward_iterator_tag;
28 using value_type = std::decay_t<std::invoke_result_t<
29 Projection,
typename std::iterator_traits<BaseIterator>::value_type&>>;
30 using difference_type =
31 typename std::iterator_traits<BaseIterator>::difference_type;
32 using reference = value_type&;
33 using pointer = value_type*;
35 ProjectingIterator() =
default;
36 explicit ProjectingIterator(BaseIterator it) : it_(std::move(it)) {}
37 ProjectingIterator(BaseIterator it, Projection proj)
38 : Projection(std::move(proj)), it_(std::move(it)) {}
39 ProjectingIterator(
const ProjectingIterator&) =
default;
40 ProjectingIterator(ProjectingIterator&&)
noexcept =
default;
41 ProjectingIterator& operator=(
const ProjectingIterator&) =
default;
42 ProjectingIterator& operator=(ProjectingIterator&&)
noexcept =
default;
44 bool operator==(ProjectingIterator other)
const {
return it_ == other.it_; }
45 bool operator!=(ProjectingIterator other)
const {
return it_ != other.it_; }
47 ProjectingIterator& operator++() {
52 ProjectingIterator operator++(
int) {
return ProjectingIterator{it_++}; }
54 decltype(
auto) operator*()
const {
return Projection::operator()(*it_); }
61template <
class Container,
class Projection>
62class ProjectingView :
private Projection {
64 using BaseConstIterator =
typename Container::const_iterator;
66 std::conditional_t<std::is_const_v<Container>, BaseConstIterator,
67 typename Container::iterator>;
69 using const_iterator = ProjectingIterator<BaseConstIterator, Projection>;
70 using value_type =
typename const_iterator::value_type;
72 explicit ProjectingView(Container& container)
noexcept
73 : container_(container) {}
75 ProjectingView(Container& container, Projection proj)
noexcept
76 : Projection(std::move(proj)), container_(container) {}
79 return ProjectingIterator<BaseConstIterator, Projection>{
80 container_.cbegin(),
static_cast<
const Projection&>(*
this)};
84 return ProjectingIterator<BaseConstIterator, Projection>{
85 container_.cend(),
static_cast<
const Projection&>(*
this)};
89 return ProjectingIterator<BaseIterator, Projection>{
90 container_.begin(),
static_cast<
const Projection&>(*
this)};
94 return ProjectingIterator<BaseIterator, Projection>{
95 container_.end(),
static_cast<
const Projection&>(*
this)};
98 auto begin()
const {
return cbegin(); }
99 auto end()
const {
return cend(); }
102 Container& container_;
106template <
class Container>
107ProjectingView<
const Container, impl::first> MakeKeysView(
const Container& c) {
108 return ProjectingView<
const Container, impl::first>{c};
112template <
class Container>
113ProjectingView<Container, impl::second> MakeValuesView(Container& c) {
114 return ProjectingView<Container, impl::second>{c};