function trace

B

baibaichen

hi

our internal log apis support varargs, but do not support <<, it means
that we have to write funciton tracing like this:

printf("%s(%d,%f)", functionName,iCount,dTime);

this need us write format string mannualy each time.

I think the better style looks like:
#define BetterFunctionTrace ....


BetterFunctionTrace(functioName, iCount,dTime);

Is there any way to generate the format string in the compile time
accroding to parameter type and parameter number? i.e.

function1(int,char*,double) => %s(%d,%s,%f);
function2(int,char*,double,unsigned int) => %s(%d,%s,%f,%u);

any idea?

thanks
 
J

Justin Spahr-Summers

Is there any way to generate the format string in the compile time
accroding to parameter type and parameter number? i.e.

function1(int,char*,double) => %s(%d,%s,%f);
function2(int,char*,double,unsigned int) => %s(%d,%s,%f,%u);

Part of the reason printf() and family use format strings is because
it's impossible to tell the number of arguments passed to a vararg
function, nor even the type of the next argument coming up. So
basically, you'd need to use a format string or some similar way of
passing information as a first parameter if your vararg list can
change a lot.
 
W

wijnand

Is this something you can use?

#include <iostream>
#include <string>


template <class T>
struct ToString;
// keep this empty to emit a compile time error
// when it doesn't have a associated string



// Define the format specifiers of the basic types
#define DEF0TYPE( type, str ) \
template <> \
struct ToString< type > \
{ static std::string value() { return str; } \
};

DEF0TYPE( int, "%d" )
DEF0TYPE( double, "%f" )
DEF0TYPE( char *, "%s" )
DEF0TYPE( const char *, "%s" )
DEF0TYPE( float, "%f")
DEF0TYPE( char, "%c")
/* andsoforth... */
#undef DEF0TYPE


// define the format string of a nullary function
template <class Return>
struct ToString< Return (*) () >
{
static std::string value() { return "%s()"; }
};


// unary functions
template <class Return, class T >
struct ToString< Return (*) ( T ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ")"; }
};


// binary functions
template <class Return, class T, class U >
struct ToString< Return (*) ( T , U ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ", " + ToString<U>::value() + ")"; }
};

// ternary functions
template <class Return, class T, class U, class V >
struct ToString< Return (*) ( T , U, V ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ", " + ToString<U>::value() + ", " +
ToString<V>::value() + ")"; }
};

// and so on

// a helper function, which provides a bit nicer syntax
template <class T>
std::string toString( T )
{
return ToString<T> :: value();
}

// two functions
void function1( int a, double b) {}
void function2( double x, double y, char * string) {}

int main()
{
std::cout << "format string for the main function: " <<
toString( main ) << std::endl;
std::cout << "format string of 'function1' " <<
toString( function1 ) << std::endl;
std::cout << "format stirng of 'function2' " << toString( function2)
<< std::endl;
return 0;

}


This gives as output
format string for the main function: %s()
format string of 'function1' %s(%d, %f)
format stirng of 'function2' %s(%f, %f, %s)


regard,
Wijnand Suijlen
 
R

raghukumar

Well that's perfect,
Hi wijnand,
sorry if i am using your name?

I know bits and peace about template programming, if you don't mind
can you give some advice
like which book to read for good template programming. It would be
very helpful if you can
give link to any of the articles authored by you.
 
W

wijnand

Hi Raghukumar,

I know bits and peace about template programming, if you don't mind
can you give some advice like which book to read for good template
programming.

I learned it from:
C++ Template Metaprogramming
by David Abrahams and Aleksey Gurtovoy
which is a book in the C++ In-Depth Series
ISBN:0-321-22725-5

Because C++ TMP is like functional programming, I had much help from
past experience in Haskell. This language I learned from the book:

The Haskell School of Expression
by Paul Hudak
ISBN: 0-521-64408-9
It would be very helpful if you can
give link to any of the articles authored by you.
I haven't written anything about this (yet ;-) )

Happy Meta-programming!
Wijnand Suijlen
 
B

baibaichen

Thanks, it does help me

However getting such format string is also in run time not in complie
time.

-Chang
 
B

baibaichen

Is this something you can use?

#include <iostream>
#include <string>

template <class T>
struct ToString;
// keep this empty to emit a compile time error
// when it doesn't have a associated string

// Define the format specifiers of the basic types
#define DEF0TYPE( type, str ) \
template <> \
struct ToString< type > \
{ static std::string value() { return str; } \
};

DEF0TYPE( int, "%d" )
DEF0TYPE( double, "%f" )
DEF0TYPE( char *, "%s" )
DEF0TYPE( const char *, "%s" )
DEF0TYPE( float, "%f")
DEF0TYPE( char, "%c")
/* andsoforth... */
#undef DEF0TYPE

// define the format string of a nullary function
template <class Return>
struct ToString< Return (*) () >
{
static std::string value() { return "%s()"; }

};

// unary functions
template <class Return, class T >
struct ToString< Return (*) ( T ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ")"; }

};

// binary functions
template <class Return, class T, class U >
struct ToString< Return (*) ( T , U ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ", " + ToString<U>::value() + ")"; }

};

// ternary functions
template <class Return, class T, class U, class V >
struct ToString< Return (*) ( T , U, V ) >
{
static std::string value() { return std::string("%s(") +
ToString<T> :: value() + ", " + ToString<U>::value() + ", " +
ToString<V>::value() + ")"; }

};

// and so on

// a helper function, which provides a bit nicer syntax
template <class T>
std::string toString( T )
{
return ToString<T> :: value();

}

// two functions
void function1( int a, double b) {}
void function2( double x, double y, char * string) {}

int main()
{
std::cout << "format string for the main function: " <<
toString( main ) << std::endl;
std::cout << "format string of 'function1' " <<
toString( function1 ) << std::endl;
std::cout << "format stirng of 'function2' " << toString( function2)
<< std::endl;
return 0;

}

This gives as output
format string for the main function: %s()
format string of 'function1' %s(%d, %f)
format stirng of 'function2' %s(%f, %f, %s)

regard,
Wijnand Suijlen

Thanks, it does help me.
but it's in run-time, not compile time.
Is there any imporvement?

chang
 
W

wijnand

Hi Chang,

Thanks, it does help me.
but it's in run-time, not compile time.
Is there any imporvement?

So what you want is a string literal? The only way you can obtain
those is with the preprocessor. There you are in trouble, because the
preprocessor knows nothing about types. So, the only solution I can
think of is to build and use a small code generator to do just this.

Wijnand
 
R

raghukumar

Hi Raghukumar,



I learned it from:
C++ Template Metaprogramming
by David Abrahams and Aleksey Gurtovoy
which is a book in the C++ In-Depth Series
ISBN:0-321-22725-5

Because C++ TMP is like functional programming, I had much help from
past experience in Haskell. This language I learned from the book:

The Haskell School of Expression
by Paul Hudak
ISBN: 0-521-64408-9


I haven't written anything about this (yet ;-) )

Happy Meta-programming!
Wijnand Suijlen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,199
Messages
2,571,045
Members
47,643
Latest member
ashutoshjha_1101

Latest Threads

Top