Skip to content

Instantly share code, notes, and snippets.

Created May 15, 2013 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/5587105 to your computer and use it in GitHub Desktop.
Save anonymous/5587105 to your computer and use it in GitHub Desktop.
map interface proxy for protobuf
#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, typename T_Key, typename T_Value>
class map_proxy
{
typedef ::google::protobuf::RepeatedPtrField<T_Pair> container_type;
container_type* m_container;
T_Key* (T_Pair::*m_get_key)();
T_Value* (T_Pair::*m_get_value)();
public:
map_proxy(::google::protobuf::RepeatedPtrField<T_Pair>* container,
T_Key* (T_Pair::*get_key)(),
T_Value* (T_Pair::*get_value)())
: m_container(container),
m_get_key(get_key),
m_get_value(get_value)
{
}
T_Value& operator[](const T_Key& key);
};
template <typename T_Pair, typename T_Key, typename T_Value>
T_Value&
map_proxy<T_Pair, T_Key, T_Value>::operator[](const T_Key& key)
{
T_Pair* elem = 0;
for (typename container_type::iterator i=m_container->begin();
i != m_container->end();
++i)
{
if (*((*i).*m_get_key)() == key)
{
elem = &(*i);
break;
}
}
if (elem == 0)
{
elem = m_container->Add();
*(elem->*m_get_key)() = key;
}
return *(elem->*m_get_value)();
}
template <typename T_Pair, typename T_Key, typename T_Value>
map_proxy<T_Pair, T_Key, T_Value>
make_map_proxy(::google::protobuf::RepeatedPtrField<T_Pair>* container,
T_Key* (T_Pair::*get_key)(),
T_Value* (T_Pair::*get_value)())
{
return map_proxy<T_Pair, T_Key, T_Value>(container, get_key, get_value);
}
int main()
{
Foo f;
/* "native" way */
Pair* p = f.mutable_my_map()->Add();
p->set_key("foo");
p->set_value("bar");
/* my way */
auto mp = make_map_proxy(f.mutable_my_map(),
&Foo::Pair::mutable_key,
&Foo::Pair::mutable_value);
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