Boost logo

Boost Users :

From: Michael Marcin (mmarcin_at_[hidden])
Date: 2007-10-10 15:24:43


Hello,

I have the MPL book and I've used some metaprogramming before but I'm
always at the edge of my understanding of the language when I do it. I
have a problem right now which I suspect is trivial but I can't for the
life of me figure out how to do it.

I have a list of 25 resource types (class Sound, class Script, etc.) and
since they are not mutable I want to share them so I have a resource
cache template that looks something like:

template< typename Resource >
class Cache
{
public:
    typedef typename Tag<Resource>::type resource_tag;

    /// Retrieve a resource by id
    /// Throws cache_error if the resource couldn't be found in the
Repository
    Resource& Retrieve( ResourceId id )
    {
       // is the resource in the cache?
       typename ResourceMap::iterator it = m_resources.find( id );
       if( it != m_resources.end() )
       {
          return it->second;
       }
       else
       {
          return LoadResource( id );
       }
    }

    /// Clears the cache and destructs all cached resources.
    void Clear()
    {
       m_resources.clear();
    }

private:

    Resource& LoadResource( ResourceId id )
    {
       Stream stream( Repository::Instance().Retrieve( id,
resource_tag::type::value ) );
       if( !stream.fail() )
       {
          Resource* res = new Resource(stream);
          m_resources.insert( id, res );
          return *res;
       }
       else
       {
          throw cache_error( id, resource_tag::type::value );
       }
    }

    typedef boost::ptr_map< ResourceId, Resource > ResourceMap;
    ResourceMap m_resources;
};

I have a class which must contain a Cache for each of the 25 resource
types and support calls to get a resource of a particular type given an
id and be able to call Clear on all 25 caches. Something like

class Manager
{
public:
    /// Returns Cache<Resource>::Retrieve( id )
    template< typename Resource >
    const Resource& Get( ResourceId id );

    /// Calls Cache::Clear for all resource types
    void Clear();
};

It would be pretty easy to just copy and paste it out 25 times but I
would like to reduce code duplication and simplify maintenance through
metaprogramming.

I have a private boost::mpl::list25 named resource_list containing all
the resource types. I think I need to transform that in to a
boost::fusion::map of 25 Resource to Cache<Resource> pairs but I'm not
sure that is what I really need to do or how to go about doing that.

Thanks,

Michael Marcin


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