Boost logo

Boost :

From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2006-01-08 05:37:23


Hi,

  These days I was trying to use boost::variant to create a read-write
lock with many priority policies (reader priority, writer priority,
alternating...). Each of this policies need different members (some need
one mutex and two condition variables, other two mutexes and one
condition variable...). These can be expensive OS resources. Trying to
optimize resources I wanted to use boost::variant. The constructor of
the read-write lock takes an argument with the wanted policy (just like
boost::read_write_mutex) and I need to initialize resources according to
this run-time policy.

The problem is that I can't directly call the correct constructor,
because boost::variant requires a convertible type to possible internal
types to call that constructor. What I would propose is the possibility
of selecting via integer value which member of boost::variant will be
constructed, just like which() returns the index of constructed member.
This way, we can efficiently compact members of classes.

class MyRWLock
{
    public:
    enum { r_prioriy, w_prioriy, a_prioriy };

    MyRWLock(int run_time_policy);

    private:
    struct r_prioriry_members
    {
     //...
    };
    struct w_prioriry_members
    {
     //...
    };
    struct a_prioriry_members
    {
     //...
    };

    //Union of needed members
    boost::variant<r_prioriry_members,
                   w_prioriry_members,
                   a_prioriry_members> m_data;
};

inline MyRWLock::MyRWLock(int run_time_policy)
: m_data(/*what do I have to do to select a constructor?*/)
{

}

Since an integer can be a convertible parameter of one variant type
constructor, maybe we can use a wrapper holding the integer as variant
argument.

namespace boost
{
   struct int_selection
   {
      explicit int_selection(int selection)
      : m_selection(selection){}

      int get_selection const { return m_selection; }
      private:
      int m_selection;
   }
}

I don't know if this feature is hard to achieve generically (that would
require big meta-programming implementation, surely), but this bounded
factory-like interface (constructing one of selected types from an
integer) would be in my opinion a big win.

One alternative is to have the first variant type as a dummy type whose
default constructor is trivial and after that use operator=. But that
can require dynamic memory (according to variant documentation). Do you
see this as an unneeded feature or it's just too hard to implement?

Regards,

Ion


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