Sup guys ..
So , the thing is that i need to define a preprocessor directive so i can compile correctively an SQL pseudocode into C++ .

VALUES (value1, value2, ...);//cant figure out a way to take the value1,...,valueX out

value1,value2,...,valueX is string or integer typed expression
for example : VALUES ("Book", "Chapter", 3);

is there any way to convert that sort of expression using #define directives , with a notice that I CANNON OVERLOAD THE "comma , " operator because i got string and int objects
string : Book,Chapter
int : 3

cause in any other case i just could #define VALUES evoke_constructor().method() or so , overload the comma operator , pull out the value1,..valueX dump them on vector-array and Ok..

plz help me on this one , i have stucked at this point about a day , how can i pull the values value1,..valueX out

Thx in advance ..

Recommended Answers

All 4 Replies

Here an example is given:

#define VALUE(value1,value2)  strcpy(val1,value1);\
strcpy(val2,value2);\
cout<<val1<<endl<<val2<<endl;


main()
{
char val1[30],val2[30];  // these variables are used to store the string passed
VALUE("abc","def");
}

You can follow this if sufficient.

commented: Perfect example of how NOT to use C macros +0

damn i didnt think of that , well thank you , its a nice idea , but a bit less practical cause i dont know the exact number of arguments :/

but a bit less practical cause i dont know the exact number of arguments

One option is to use the boost preprocessor metaprogramming library.
http://www.boost.org/doc/libs/1_45_0/libs/preprocessor/doc/index.html

For example,

file /tmp/pp.h

#include <boost/preprocessor.hpp>
#include <boost/any.hpp>
#include <vector>

#define repeat_this( place_holder, N, CNTR ) CNTR.push_back( boost::any( Argument ## N ) ) ;

#ifndef BOOST_PP_IS_ITERATING
# ifndef PP_H_INCLUDED
# define PP_H_INCLUDED

// no args case
std::vector< boost::any > make_sequence() { return std::vector< boost::any >() ; }

#define BOOST_PP_ITERATION_LIMITS ( 1, 16 )
#define BOOST_PP_FILENAME_1 "/tmp/pp.h"
#include BOOST_PP_ITERATE()
# endif
#else
# define N BOOST_PP_ITERATION()

// 1 to 16 args case
template < BOOST_PP_ENUM_PARAMS( N, typename T ) >
std::vector< boost::any > make_sequence( BOOST_PP_ENUM_BINARY_PARAMS( N, T, Argument ) )
{
    std::vector< boost::any > many ;
    BOOST_PP_REPEAT( N, repeat_this, many)
    return many ;
}

#endif

file check_it_out.cc

#include "/tmp/pp.h"
#include <string>
#include <iostream>

void print_types( const std::vector< boost::any >& seq )
{
    for( std::vector< boost::any >::size_type i =0 ; i < seq.size() ; ++i )
    {
        if( seq[i].type() == typeid(int) ) std::cout << "int " ;
        else if( seq[i].type() == typeid(double) ) std::cout << "double " ;
        else if( seq[i].type() == typeid(std::string) ) std::cout << "string " ;
        else std::cout << "some_other_type " ;
    }
    std::cout << '\n' ;
}

int main()
{
    int i = 6, j = 7, k = 8 ;
    double d = 9, e = 10 ;
    std::string str = "hello world" ;

    print_types( make_sequence( i, j, d ) ) ;
    print_types( make_sequence( i, d, str, j, e ) ) ;
    print_types( make_sequence( str, e, i, d, j, k ) ) ;
}

>g++45 -Wall -std=c++98 -pedantic -Werror -I /usr/local/include check_it_out.cc
>./a.out
int int double
int double string int double
string double int double int int
>


Another (much neater) option is to use C++1x variadic templates: http://www.devx.com/cplus/Article/41533

#include <boost/any.hpp>
#include <vector>
#include <string>
#include <iostream>

// 1 arg case
template< typename T > void push_back( std::vector< boost::any >& seq, const T& v )
{ seq.push_back(v) ; }

// 2 or more args case
template< typename T, typename ... ARGS >
void push_back( std::vector< boost::any >& seq, const T& v, const ARGS& ... args )
{
    seq.push_back( v ) ;
    push_back( seq, args ... ) ;
}

template< typename CONTAINER > void print_types( const CONTAINER& seq )
{
    for( typename CONTAINER::size_type i = 0 ; i < seq.size() ; ++i )
    {
        if( seq[i].type() == typeid(int) ) std::cout << "int " ;
        else if( seq[i].type() == typeid(double) ) std::cout << "double " ;
        else if( seq[i].type() == typeid(std::string) ) std::cout << "string " ;
        else std::cout << "some_other_type " ;
    }
    std::cout << '\n' ;
}

int main()
{
    int i = 6, j = 7, k = 8 ;
    double d = 9, e = 10 ;
    std::string str = "hello world" ;

    std::vector< boost::any > sequence ;
    push_back( sequence, i, str, j, d, k, e ) ;
    print_types( sequence ) ;
}

>g++45 -Wall -std=c++0x -pedantic -Werror -I /usr/local/include variadic.cc
>./a.out
int string int double int double
>

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.