Boost logo

Boost Users :

Subject: Re: [Boost-users] Using different variables based on template type
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-06-02 08:58:13


On Tue, Jun 2, 2009 at 2:31 AM, Ryan McConnehey <mccorywork_at_[hidden]>wrote:

> Scott McMurray wrote:
>
>> They're at least simple, but it's still a violation of DRY,
>> so I'm not a big fan.
>>
>>
> If a non-expanding interface is needed (non-template so that every type
> isn't accepted) does it really violate DRY?
>
> What are the types really, anyways?
>>
> I've create true_typedef of the basic type like uint16, uint32, int16, etc.
> I've written my own serialization interface (I know boost already has one)
> and I'm restricting the interface to only allow certain types. I'm trying
> to centralize the were the real work happens so if new types are needed then
> added them won't be difficult.
>

Is there any reason you have to have different names for the map? Use
template specialization to achieve the same thing as name resolution for you
but still allowing you to access the maps through a consistent naming
scheme.

//The default specialization will cause compilation to fail unless
DECL_SERIALIZATION_SUPPORT(T) has been called for a type
#define BEGIN_SERIALIZATION_DECLS() \
    namespace serialization { \
        template<typename T> struct kv_map { }; \

#define DECL_SERIALIZATION_SUPPORT(T) \
        template<> \
        struct kv_map<T> \
        { \
            typedef std::map<std::string, T> map_type; \
            map_type map; \
        }; \
        kv_map<T>::map_type map;

#define END_SERIALIZATION_DECLS() }

template<typename T> void store_kv(const std::string& key, const T& value)
{
    serialization::kv_map<T>::map[key] = value;
}

template<typename T> T& retrieve_kv(const std::string& key)
{
    return serialization::kv_map<T>::map[key];
}

now you don't even need the put function at all anymore, and you can invoke
it like this:

BEGIN_SERIALIZATION_DECLS()
DECL_SERIALIZAITON_SUPPORT(boost::uint16_t)
DECL_SERIALIZATION_SUPPORT(boost::uint32_t)
END_SERIALIZATION_DECLS()

boost::uint16_t test1 = 7;
boost::uint32_t test2 = 8;

store_kv("test1", test1);
store_kv("test2", test2);

test1 = retrieve_kv<boost::uint16_t>("test1");
test2 = retrieve_kv<boost::uint32_t>("test2");

If you need to provide different storage / retrieval logic for different
types then just specialize the store_kv and retrieve_kv functions. When you
want to support a new type you only add 1 line of code, a
DECL_SERIALIZATION_SUPPORT macro.

I used a very similar method to this to provide compile-time lookup of the
names of the different fields in an enum and it works well.



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net