$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Sven Van Echelpoel (sven.vanechelpoel.sv_at_[hidden])
Date: 2002-05-15 07:24:48
Hi y'all,
I missed the original discussion on the operator%-vs-arg() issue, but
after reading Samuel's last mail I got an idea. A syntax like the one
below is a little bit more expressive that simply format() % ... % ...
formatter fmt;
fmt.format( "Enter a number between %p1 and %p2" )
%p1( 10 )
%p2( 100 );
Don't you think. Here's how I achieved it (on the top of my head):
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
class format_param;
class formatter
{
public:
formatter& operator % ( format_param const& );
formatter& format( char const* fmt )
{
mResult = fmt;
return ( *this );
}
string const& str()
{
return ( mResult );
}
private:
string mResult;
};
class format_param
{
public:
void replace( std::string& s ) const
{
string::size_type sidx = s.find( param_id );
if ( string::npos != sidx )
{
string tmp = s.substr( 0, sidx );
tmp += oss.str();
if ( sidx + param_id.length() < s.length() )
{
tmp += s.substr( sidx + param_id.length() );
}
s = tmp;
}
}
protected:
format_param( char const* id ) :
param_id( id )
{
}
template<typename T>
void preformat( T const& t )
{
oss << t;
}
private:
string param_id;
ostringstream oss;
};
class p1 : public format_param
{
public:
template<typename T>
p1( T const& t ) :
format_param( "%p1" )
{
preformat( t );
}
};
class p2 : public format_param
{
public:
template<typename T>
p2( T const& t ) :
format_param( "%p2" )
{
preformat( t );
}
};
// more of these classes p3...pN
formatter& formatter::operator%( format_param const& param )
{
param.replace( mResult );
return ( *this );
}
int main(int argc, char* argv[])
{
formatter fmt;
fmt.format( "Enter a number between %p1 and %p2" )
%p1( 10 )
%p2( 100 );
cout << fmt.str() << endl;
return 0;
}
Of course, using this technique you wouldn't be able to specify
additional formatting options, but I have some ideas on that front as
well, although I don't yet know if they can be implemented. One syntax
looks a bit like this (haven't tried any code yet, so it might as well
prove to be impossible, but by showing it, it might spawn other
alternatives):
format( "%p1" ) %p1( 10 ) [Hex][Width=10];
I will think on it some more. An even nicer syntax would be:
format( "%p1" )
p1 = 10 [Hex][Width=10];
or something similar, but I know I might be stretching things a wee bit
(I'm not a standardite :) ). One idea is to let p1 be a global of a type
whose assignment operator returns something that can be inserted into
the expression (equally in [Width=10]). I'll ponder on it some more
while you chew this one.
Svenne.
-- If you can remain calm while all others around you are losing their heads, maybe you just don't understand the problem.