Boost logo

Boost :

Subject: Re: [boost] [flyweight] key value with objects not constructible from a key
From: Joaquin M Lopez Munoz (joaquin_at_[hidden])
Date: 2008-11-12 17:53:36


Scott McMurray <me22.ca+boost <at> gmail.com> writes:

>
> On Wed, Nov 12, 2008 at 17:11, Michael Marcin <mike.marcin <at> gmail.com>
> wrote:
> >
> > But loaded_texture's can't share any state or be initialized with state
> > other than the key.
> >
>
> But if you load a value one way, I'm not convinced that getting a
> version that happens to have the same key but was loaded differently
> is something that should be encouraged.
>
> Why not just make your key more complex, since you need to pass all
> the information needed to construct one when you retrieve one anyways?

The following might be one possible approach to your envisioned
scenario using the technique proposed by Scott. There is one
significant difference with the way TextureFactory is defined,
namely that construct is required to return a Texture (your
version does the construction using placement new).
Complete sample follows:

***BEGIN CODE***
#include <boost/assert.hpp>
#include <boost/flyweight.hpp>
#include <boost/flyweight/key_value.hpp>
#include <string>
#include <cassert>

using namespace boost::flyweights;

struct Texture
{
};

struct Log
{
};

struct TextureFactory
{
  TextureFactory(const Log&){}

  Texture construct(const std::string& filename)
  {
    return Texture(); // real code would do something different
  }
};

struct KeyAndFactory
{
  KeyAndFactory(const std::string key,TextureFactory& factory):
    key(key),pfactory(&factory)
  {}

  std::string key;
  TextureFactory* pfactory;
};

std::size_t hash_value(const KeyAndFactory& kf)
{
  boost::hash<std::string> h;
  return h(kf.key);
}

bool operator==(const KeyAndFactory& kf1,const KeyAndFactory& kf2)
{
  return kf1.key==kf2.key;
}

struct LoadedTexture:Texture
{
  LoadedTexture(const KeyAndFactory& kf):
    Texture(kf.pfactory->construct(kf.key))
  {}
};

typedef flyweight<key_value<KeyAndFactory,LoadedTexture> >
TextureFlyweight;

int main()
{
  Log log1,log2;
  TextureFactory factory1(log1),factory2(log2);

  TextureFlyweight fw1("hello",factory1);
  TextureFlyweight fw2("hello",factory2);
  TextureFlyweight fw3("bye",factory1);
  const Texture& t1=fw1;

  assert(fw1==fw2);
  assert(fw1!=fw3);
}

***END CODE***

Is this more similar to what you have in mind?

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk