Brian,

Brian Simpson wrote:
> A fundamental problem encountered by boost::variant is that of invoking an
> overloaded function for the correct type, where the type is not known
until
> runtime.  As near as I can tell, all proposed solutions to this problem
have
> involved uncomfortable space or time tradeoffs.  I have read several posts
> which asked why we couldn't use a switch statement--it would avoid the
> expenses of the current solutions without incurring any of its own.
> Until recently, I agreed with those (whose expertise I highly respect) who
> said it was not possible.

I don't think anyone ever said it wasn't possible. It was just whether it
would actually improve anything -- i.e., it was unclear whether compilers
would optimize recursively-inlined switch statements better than
recursively-inlined if statements.


> However, while perusing the source for the current implementation of
> boost::variant, a possible solution occurred to me.
> I have spent some time fleshing out the proposed solution, and it seems to
> be all standard C++ (no non-standard).  I think it might be referred to as
> "sequence unrolling".
> Here's how it works:
[snip]
>
> Questions or comments?

Sorry, I've just gotten back from vacation. I haven't spent *too* much time
looking through your code, but I can't see how it improves on my current
code, which features sequence unrolling. If you could explain to me I'd
appreciate it.


> p.s.  I must acknowledge Itay's and Eric's efforts in the current
> implementation of boost::variant.  I've learned a lot just from studying
the
> code.

Thanks! It's nice to know our efforts are being recognized :)


> It was while I was browsing the recently added implementation of
> switched type selection based on the variadic template parameters that
this
> idea occurred to me.

Wait, hold on a second. The current implementation isn't tied to any
particular "unrolling constant." The current visitation mechanism after
preprocessing should like like this (see function template
apply_visitor_impl):

  typedef typename step0::type T0;
  typedef typename step0::next step1;
  typedef typename step1::type T1;
  typedef typename step1::next step2;
  // ...and so on until unrolling constant...

  switch (var_which)
  {
    case (Which::value + (0)):
        return apply_visitor_impl(visitor, storage, static_cast<T0*>(0),
1L);
    case (Which::value + (1)):
        return apply_visitor_impl(visitor, storage, static_cast<T1*>(0),
1L);
    // ...and so on until unrolling constant...
  }

  // ...else continue unrolling next "chunk" of types (by recursively
calling the above w/ stepN)...

Thus, if we are to assume O(1) complexity for a switch, then the complexity
of the visitation mechanism becomes O( N / unrolling-size ), where
unrolling-size is exposed as BOOST_VARIANT_APPLY_VISITOR_UNROLLING_LIMIT. I
think this is as good as it gets.

Let me know if your implementation is achieving a better result.

Thanks,
Eric



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to