Boost logo

Boost :

From: Max Khesin (MKhesin_at_[hidden])
Date: 2004-05-19 12:33:38


I have been playing around with a library to emulate Python 'in' syntax

if(a in [x1, x2]):
        stuff

the main motivation for this is the annoyance of repeating the || operator
with the same value in C++

if(val==v1 || val==v2 || val==v3){
  ^^^ ^^^ ^^^
}

I figured I would use tuple for the list to allow membership test for a list
of heterogeneous types (just like python).
The rough results are included below.

I am interested in your feedback:
1) how useful would you find this in general
2) there are 3 variations on syntax in the main() 1st is native(no macros)
with more typing, 2 is less typing with macros, 3d is even less but does not
compile :) (coule use a language lawer here). Do you like any of these?
Alternative suggestions?
3) implementation - is it correct (I know it's not since is_convertible is
used to mean is_comparable, any suggestion), can it be simplified internally
or by using other boost libs?

thanks,
max

/////////////////////////////////////////////////////////////////

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>
#include <boost/type_traits/is_convertible.hpp>

#include <iostream>

using std::cout;

// compare the values is they are comparable (is_convertible is not
// good enough for all cases, suggestions?)
template<bool>
struct compare_convertible;

template<>
struct compare_convertible<false>
{
    template<class T1, class T2>
        bool operator()(const T1&, const T2& ){return false;}
};

template<>
struct compare_convertible<true>
{
    template<class T1, class T2>
        bool operator()(const T1& val1, const T2& val2){return val1==val2;}
};

template<class T1, class T2>
bool compare_if_convertible(const T1& val1, const T2& val2)
{
    return compare_convertible<boost::is_convertible<T2, T1>::value>()(val1,
val2);
}

template<class T, class TupleT>
bool contains(const T& val, const TupleT& the_tuple)
{
    return (compare_if_convertible(val, the_tuple.get_head()) // check
head
                ||
                (boost::tuples::length<TupleT::tail_type>::value// not empty

                    &&
                    contains(val, the_tuple.get_tail()))); // check
tail
}

// value wrapper, provides the -- part of the --> syntax
template<class T>
struct Element
{
    const T& val;
    const Element& operator--(int)const {return *this;}
    Element(const T& val_):val(val_){}
};

template<class T>
Element<T> element(const T& val)
{
    return Element<T>(val);
}

// provides the '>' part of the '-->' syntax
template<class ElemT, class T1, class T2>
bool operator>(const Element<ElemT>& element, const boost::tuples::cons<T1,
T2> the_tuple)
{
    return contains(element.val, the_tuple);
}

#define in -->boost::make_tuple
#define in2 >boost::make_tuple

int main(int argc, char* argv[])
{
    if(element(1.4) --> boost::make_tuple(1, "aa", 1.2))
    {
        std::cout<<"yahuuu\n";
    }
    if(element(1.0) in (1, "aa", 1.2))
    {
        std::cout<<"yahuuu\n";
    }
#if 0
// will not compile due to
// test.cpp(92) : error C2784: 'bool operator >(const Element<ElemT>
&,const boost:
// :tuples::cons<T1,T2>)' : could not deduce template argument for 'const
Element<T
// > &' from 'double'
// test.cpp(73) : see declaration of 'operator`>''
// test.cpp(92) : error C2677: binary '>' : no global operator found
which takes ty
// pe
'boost::tuples::detail::make_tuple_mapper<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>::ty
p
// e' (or there is no acceptable conversion)
// with
// [
// T0=int,
// T1=const char [3],
// T2=double,
// T3=boost::tuples::null_type,
// T4=boost::tuples::null_type,
// T5=boost::tuples::null_type,
// T6=boost::tuples::null_type,
// T7=boost::tuples::null_type,
// T8=boost::tuples::null_type,
// T9=boost::tuples::null_type
// ]
//

    if(1.0 in2(1, "aa", 1.2))
    {
        std::cout<<"yahuuu\n";
    }
#endif
    return 0;
}

This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail.


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