|
Boost : |
From: Tom Becker (voidampersand_at_[hidden])
Date: 2001-12-24 15:41:40
On Mon, 24 Dec 2001 02:44:38 +0800, joel de guzman wrote:
>----- Original Message -----
>From: "Keith Burton" :
> > Sorry I was unclear
>>
>> most long expressions contain many ()s but not many contain %
>> therefore it is easier to see what is each parameter
>
>No one ever wins this battle over syntax. It's always very subjective.
>My favorite color is blue, hers is red, which is better and which
>should we choose for our new car? A compromise? violet?
>akkk, I don't think so :-)
How about if it supports printf syntax? Anything that departs from
printf syntax is likely to be perceived as a compromise, unless it's
clearly better. But the main problem with printf is its lack of type
safety. I think people are pretty comfortable with the syntax. So if
we could keep the familiar syntax and use C++ to provide type safety,
people might like it.
cout << format("%d, %f", x, y) << endl;
Here's a really quick and dirty example I threw together to show what
I'm thinking. The formatting code in 'tostream' is just a dummy to
show that it has access to all the arguments by index. A real
formatter should actually use the format string. There are some
obvious optimizations, and I'm sure there's plenty of places where it
could be better, but the main thing is I wanted to get something out
where people could comment on it.
Regards,
Tom
#include <iostream>
#include <string>
#include <vector>
using std::ostream;
using std::string;
using std::cout;
using std::endl;
using std::vector;
struct formatter
{
formatter(const char* f) :
f_(f)
{
}
void tostream(ostream& out) const
{
out << f_;
int n = arg_ptrs_.size();
for (int i = 0; i < n; ++i)
{
out << " ";
arg_getters_[i](arg_ptrs_[i], out);
}
}
typedef void (*arg_getter)(void* arg_ptr, ostream& out);
template<typename T>
static void get_arg(void* arg_ptr, ostream& out)
{
out << *reinterpret_cast<T*>(arg_ptr);
}
vector<void*> arg_ptrs_;
vector<arg_getter> arg_getters_;
const char* f_;
};
inline ostream& operator<<(ostream& out, const formatter& f)
{
f.tostream(out);
return out;
}
template<typename T1>
struct formatter1 : public formatter
{
formatter1(const char* f, T1 a1) :
formatter(f)
{
arg_ptrs_.push_back(&a1);
arg_getters_.push_back(&get_arg<T1>);
}
};
template<typename T1, typename T2>
struct formatter2 : public formatter1<T1>
{
formatter2(const char* f, T1 a1, T2 a2) :
formatter1(f, a1)
{
arg_ptrs_.push_back(&a2);
arg_getters_.push_back(&get_arg<T2>);
}
};
inline formatter format(const char* f)
{
return formatter(f);
}
template<typename T1>
inline formatter1<T1> format(const char* f, T1 a1)
{
return formatter1<T1>(f, a1);
}
template<typename T1, typename T2>
inline formatter2<T1, T2> format(const char* f, T1 a1, T2 a2)
{
return formatter2<T1, T2>(f, a1, a2);
}
int main()
{
short x = 2;
float y = 3.14;
cout << format("%d, %f", x, y) << endl;
return 0;
}
-- -- Tom Becker "Within C++, there is a much smaller and <voidampersand_at_[hidden]> cleaner language struggling to get out." -- Bjarne Stroustrup
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk