Opened 17 years ago

Last modified 8 years ago

#547 closed Feature Requests (fixed)

[variant] Compile time checked getter — at Version 7

Reported by: nobody Owned by: Antony Polukhin
Milestone: Boost 1.58.0 Component: variant
Version: None Severity: Optimization
Keywords: Cc:

Description (last modified by Antony Polukhin)

[Sorry if anyone feels bad about this, I already posted
it in usera and devel lists, with no answer at all]


During a redesign, I began using boost::variant, and I
detected that trying to get a value of a type not
included in variant type-list resulted in run-time
error (cast or null pointer).

I feel that a variant should only try to return a valid
type from its type-list, otherwise giving a compiler
error, and reserve runttime errors for that case when
someone tries to get a value from a type contained in
the typelist, but not the actual type contained in the
actual object.

In such a way, I have made a little redesign on
boost::get and called it boost::checked_get:

namespace boost {

template <typename U,
BOOST_VARIANT_ENUM_PARAMS(typename T) >
inline
    typename add_pointer<U>::type
checked_get(
      boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >*
operand
      BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
    )
{
    typedef boost::variant<
BOOST_VARIANT_ENUM_PARAMS(T) > Variant;

    /* throw a compile-time error if type is not
contained on type
list */
    BOOST_STATIC_ASSERT((!is_same<
        typename mpl::find<typename
Variant::types,U>::type,
        typename mpl::end<typename
Variant::types>::type>::value));

    typedef typename add_pointer<U>::type U_ptr;
    if (!operand) return static_cast<U_ptr>(0);

    detail::variant::get_visitor<U> v;
    return operand->apply_visitor(v);
}

} // end of addition to namespace boost


And, of course, the rest of the templates needed for
const *, ref and const&..

I think it would be interesting to include it in boost
libraries. In fact, I use it intensely.

Best regards,

Zara (yozara@terra.es)

Change History (7)

comment:1 by yozara, 17 years ago

Logged In: YES 
user_id=1424465

(It is me again, but this time I am logged in)

Best regards,

Zara

comment:2 by ebf, 17 years ago

Logged In: YES 
user_id=120427

Hi Zara,

I like this idea, and in fact a similar feature was proposed
by another user as well some time ago. I don't have time
right now though to add the tests and documentation that
would need to accompany this change...

Another issue to think about: I would imagine checking is
likely almost always useful when using a variant in
non-generic contexts, but I can envision a generic context
where unchecked behavior would be desirable. I am not sure
then whether it is better to have the default "get" be
unchecked (as currently) or checked (as proposed). Leaving
get as unchecked does not introduce backward compatibility
issues, but it may be the right thing to do (and then
introduced an "unchecked_get" or something similar).

I'd be interested in your thoughts.

Eric

comment:3 by yozara, 17 years ago

Logged In: YES 
user_id=1424465

Well, my proposal is to keep get as is, and add the
checked_get family of functions. No code will be broken, and
it would be easy to upgrade it with new funcitons, if desired.

Zara

comment:4 by ebf, 15 years ago

Component: Nonevariant
Owner: changed from nobody to ebf
Severity: Showstopper
Status: assignednew

comment:5 by ebf, 15 years ago

Severity: ShowstopperOptimization

comment:6 by ebf, 15 years ago

Status: newassigned

comment:7 by Antony Polukhin, 8 years ago

Description: modified (diff)
Milestone: Boost 1.58.0
Owner: changed from ebf to Antony Polukhin
Status: assignednew

Series of commits were merged to develop branch to fix this issue. At this moment last commit is cbf4bbf

Note: See TracTickets for help on using tickets.