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};