Skip to content

Instantly share code, notes, and snippets.

@eruffaldi
Last active October 28, 2015 11:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eruffaldi/93d09ed6644ae3fa279f to your computer and use it in GitHub Desktop.
Save eruffaldi/93d09ed6644ae3fa279f to your computer and use it in GitHub Desktop.
Iterate over keys or values of a std::map alike in C++
#include <map>
#include <unordered_map>
#include <iostream>
/// Used to iterate over the values of a map
template <class Mapclass>
struct map_keys
{
using map_t = Mapclass;
struct iterator
{
using realiterator_t = typename std::conditional<std::is_const<map_t>::value,typename map_t::const_iterator,typename map_t::iterator>::type;
using value_t = typename std::add_const<typename map_t::key_type>::type;
realiterator_t under;
iterator(realiterator_t x) : under(x) { }
auto operator*() -> typename std::add_lvalue_reference<value_t>::type { return under->first; }
auto operator->() -> typename std::add_pointer<value_t>::type { return &under->first; }
bool operator != (const iterator& o) const
{
return under != o.under;
}
iterator & operator++()
{
++under;
return *this;
}
iterator operator++(int)
{
iterator x(*this);
++under;
return x;
}
};
map_keys(map_t & x) : x_(x) {}
iterator begin() { return iterator(x_.begin()); }
iterator end() { return iterator(x_.end()); }
unsigned int size() const { return x_.size(); }
map_t & x_;
};
/// Used to iterate over the values of a map
template <class Mapclass>
struct map_values
{
using map_t = Mapclass;
struct iterator
{
using realiterator_t = typename std::conditional<std::is_const<map_t>::value,typename map_t::const_iterator,typename map_t::iterator>::type;
using value_t = typename std::conditional<std::is_const<map_t>::value,typename std::add_const<typename map_t::mapped_type>::type,typename map_t::mapped_type>::type;
realiterator_t under;
iterator(realiterator_t x) : under(x) { }
auto operator*() -> typename std::add_lvalue_reference<value_t>::type { return under->second; }
auto operator->() -> typename std::add_pointer<value_t>::type { return &under->second; }
bool operator != (const iterator& o) const
{
return under != o.under;
}
iterator & operator++()
{
++under;
return *this;
}
iterator operator++(int)
{
iterator x(*this);
++under;
return x;
}
};
map_values(map_t & x) : x_(x) {}
iterator begin() { return iterator(x_.begin()); }
iterator end() { return iterator(x_.end()); }
unsigned int size() const { return x_.size(); }
map_t & x_;
};
template <class Key, class Value>
map_keys<std::map<Key,Value> > make_map_keys(std::map<Key,Value>& x)
{
return map_keys<std::map<Key,Value> >(x);
}
template <class Key, class Value>
map_keys<std::unordered_map<Key,Value> > make_map_keys(std::unordered_map<Key,Value>& x)
{
return map_keys<std::unordered_map<Key,Value> >(x);
}
template <class Key, class Value>
map_keys<const std::map<Key,Value> > make_map_keys(const std::map<Key,Value>& x)
{
return map_keys<const std::map<Key,Value> >(x);
}
template <class Key, class Value>
map_keys<const std::unordered_map<Key,Value> > make_map_keys(const std::unordered_map<Key,Value>& x)
{
return map_keys<const std::unordered_map<Key,Value> >(x);
}
template <class Key, class Value>
map_values<std::map<Key,Value> > make_map_values(std::map<Key,Value>& x)
{
return map_values<std::map<Key,Value> >(x);
}
template <class Key, class Value>
map_values<const std::map<Key,Value> > make_map_values(const std::map<Key,Value>& x)
{
return map_values<const std::map<Key,Value> >(x);
}
template <class Key, class Value>
map_values<std::unordered_map<Key,Value> > make_map_values(std::unordered_map<Key,Value>& x)
{
return map_values<std::unordered_map<Key,Value> >(x);
}
template <class Key, class Value>
map_values<const std::unordered_map<Key,Value> > make_map_values(const std::unordered_map<Key,Value>& x)
{
return map_values<const std::unordered_map<Key,Value> >(x);
}
int main(int argc, char const *argv[])
{
std::map<int,std::string> x;
x[10] = "ciao";
x[20] = "pippo";
const std::map<int,std::string> cx = x;
for(auto y : make_map_keys(x))
std::cout << " " << y;
std::cout << std::endl;
for(auto y : make_map_values(x))
std::cout << " " << y;
std::cout << std::endl;
for(auto y : make_map_keys(cx))
std::cout << " " << y;
std::cout << std::endl;
for(auto y : make_map_values(cx))
std::cout << " " << y;
std::cout << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment