-
-
Save qsorix/5587129 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 "foo.pb.h" | |
#include <iostream> | |
/* protocol: | |
message Foo | |
{ | |
message Pair | |
{ | |
required string key = 1; | |
required string value = 2; | |
} | |
repeated Pair my_map = 1; | |
} | |
*/ | |
template <typename T_Pair> | |
struct pair_proxy_traits | |
{}; | |
template <typename T_Pair> | |
class map_proxy | |
{ | |
typedef ::google::protobuf::RepeatedPtrField<T_Pair> container_type; | |
typedef typename pair_proxy_traits<T_Pair>::key_type key_type; | |
typedef typename pair_proxy_traits<T_Pair>::value_type value_type; | |
container_type* m_container; | |
public: | |
map_proxy(::google::protobuf::RepeatedPtrField<T_Pair>* container) | |
: m_container(container) | |
{ | |
} | |
value_type& operator[](const key_type& key); | |
}; | |
template <typename T_Pair> | |
typename map_proxy<T_Pair>::value_type& | |
map_proxy<T_Pair>::operator[](const key_type& key) | |
{ | |
T_Pair* elem = 0; | |
for (typename container_type::iterator i=m_container->begin(); | |
i != m_container->end(); | |
++i) | |
{ | |
if (pair_proxy_traits<T_Pair>::key(*i) == key) | |
{ | |
elem = &(*i); | |
break; | |
} | |
} | |
if (elem == 0) | |
{ | |
elem = m_container->Add(); | |
pair_proxy_traits<T_Pair>::key(*elem) = key; | |
} | |
return pair_proxy_traits<T_Pair>::value(*elem); | |
} | |
template <typename T_Pair> | |
map_proxy<T_Pair> | |
make_map_proxy(::google::protobuf::RepeatedPtrField<T_Pair>* container) | |
{ | |
return map_proxy<T_Pair>(container); | |
} | |
template <> | |
struct pair_proxy_traits<Foo::Pair> | |
{ | |
typedef std::string key_type; | |
typedef std::string value_type; | |
static key_type& key(Foo::Pair& pair) | |
{ | |
return *pair.mutable_key(); | |
} | |
static value_type& value(Foo::Pair& pair) | |
{ | |
return *pair.mutable_value(); | |
} | |
}; | |
int main() | |
{ | |
Foo f; | |
/* "native" way */ | |
Foo::Pair* p = f.mutable_my_map()->Add(); | |
p->set_key("foo"); | |
p->set_value("bar"); | |
/* my way */ | |
auto mp = map_proxy(f.mutable_my_map()); | |
mp["alice"] = "cat"; | |
/* debug */ | |
std::cout << f.DebugString() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment