Last active
October 28, 2015 11:15
-
-
Save eruffaldi/93d09ed6644ae3fa279f to your computer and use it in GitHub Desktop.
Iterate over keys or values of a std::map alike in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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