Boost logo

Boost Users :

Subject: Re: [Boost-users] Flyweight: wrapping shared_ptr
From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2014-10-07 12:18:50


El 07/10/2014 15:06, Akim Demaille escribió:
Hi all,

I'd like to add hash-consing on top of my hiearchy-based AST
implementation, which uses shared_ptr (I'm in C++11) to guarantee
value semantics (the pointee is const).

Below is a tiny version that would help me see if using Boost.Flyweight
is adequate.

It works, but it is not transparent, because I have to explicitly
call '.get()' on my flyweights to deference to the pointers. So for
instance my code reads:

  size_t hash() const
  {
    size_t res = 0;
    hash_combine(res, boost::hash_value(op));
    hash_combine(res, l.get()->hash());
    hash_combine(res, r.get()->hash());
    return res;
  }

where I expect to have l->hash(), not l.get()->hash().

I have tried deriving from flyweight to add an operator->, but it
fails horribly.

This is how the derivation would be done (I've tried with your code and it works,
effectively eliminating the need to do .get()-> rather than -> ):

struct Exp:boost::flyweight<Exp_>
{
  using super=boost::flyweight<Exp_>;
  using super::super;
  using element_type=super::value_type::element_type;

  const element_type& operator*() const{return *(this->get());}
  const element_type* operator->()const{return &*(this->get());}
};

bool operator==(const Exp& l, const Exp& r)
{
  return *l == *r;
}

bool operator!=(const Exp& l, const Exp& r)
{
  return !(l == r);
}

I realize that it is suboptimal to use flyweight on top of shared_ptr,
as I get two reference counters. Yet this change is less invasive than
migrating my AST hierarchy to using variants as is done in the example
of the documentation.

What would be the right approach?

I think this approach is OK: elements must be stored through some type of pointer
because they're polymorphic, and, variants banned, std::shared_ptr<Base> seems a
sensible choice. An alternative would be to use some sort of cloning smart pointer
to spare the reference count, but it's not clear to me this would be faster than
shared_ptr:

* element exists: shared_ptr creation is slower than clone_ptr creation
* element does not exist: shared_ptr creation and copy is probably faster than clone_ptr
creation and cloning.

So, if in doubt profile and determine what's best for you.

Joaquín M López Muñoz
Telefónica

________________________________

Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at:
http://www.tid.es/ES/PAGINAS/disclaimer.aspx



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