On Wednesday 23 of November 2011, Michael Meeks wrote:
On Wed, 2011-11-23 at 14:56 +0100, Lubos Lunak wrote:
And some of the arguments are rather weak as well, I can get you easy to
use and read, better to translate and similarly space efficient without
var-args. Wanna bet :) ?
Sounds great to me; of course - it'd be nice if it compiled in linear
time too without including a million lines of odd boost templated
headers ;-) but certainly; if we can get something readable, and
typesafe that compiles to something -actually-small- - ie. a single
function call & setup; I'm all for it whatever it looks like - it sounds
like the best of all worlds.
I haven't thought it out in detail, but the general idea is attached. It's
just a proof of concept, so there are some obvious problems, but I don't see
a flaw in the design. Since it's also just a single call, the in-place cost
is small and is moved to the bodies of the templates, which can be just in
one place, one per each combination of arguments (and the common instances of
the template can be externed, so it really will be just one copy). The
template code is relatively small, so I don't expect noticeable impact on
compile time. Also, funnily enough, the generated code in the place of the
call is one instruction shorter, because unlike printf() it does not need the
terminating NULL for the vararg :).
I expect it would be even possible to achieve such single in-place call even
for the LOG( "P is " << p << " and b is " << b ) case, or even do this for
string+string operation, which would turn it into the even better-looking
LOG( "P is " + p + " and b is " b ) or LOG( "P is %1 and b is %2", p, b ),
whichever would suit one's fancy (as in, both would be possible at the same
time). It would require getting a bit more creative with argument and return
types for the operator overloads, but that'd be hidden behind the scenes.
--
Lubos Lunak
l.lunak@suse.cz
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
class formater_base
{
public:
virtual void format( char* buffer ) const = 0;
};
template< typename T >
class formater : public formater_base
{
public:
formater( T data ) : data( data ) {}
virtual void format( char* buffer ) const;
private:
const T data;
};
template<>
void formater< std::string >::format( char* buffer ) const
{
strcpy( buffer, data.c_str());
}
template<>
void formater< int >::format( char* buffer ) const
{
sprintf( buffer, "%d", data );
}
template<>
void formater< const char* >::format( char* buffer ) const
{
strcpy( buffer, data );
}
void generic_format( const char* format, const formater_base& f1 )
{
char buffer[ 1024 ];
char* dst = buffer;
for( const char* pos = format;
*pos != '\0';
++pos )
{
if( *pos == '%' )
{
++pos;
if( *pos == '1' )
{
char tmp[ 1024 ];
f1.format( tmp );
strcpy( dst, tmp );
dst += strlen( tmp );
}
else if( *pos == '%' )
*dst++ = '%';
else
abort();
}
else
*dst++ = *pos;
}
*dst = '\0';
printf( "%s", buffer );
}
void generic_format( const char* format, const formater_base& f1, const formater_base& f2 )
{
char buffer[ 1024 ];
char* dst = buffer;
for( const char* pos = format;
*pos != '\0';
++pos )
{
if( *pos == '%' )
{
++pos;
if( *pos == '1' )
{
char tmp[ 1024 ];
f1.format( tmp );
strcpy( dst, tmp );
dst += strlen( tmp );
}
else if( *pos == '2' )
{
char tmp[ 1024 ];
f2.format( tmp );
strcpy( dst, tmp );
dst += strlen( tmp );
}
else if( *pos == '%' )
*dst++ = '%';
else
abort();
}
else
*dst++ = *pos;
}
*dst = '\0';
printf( "%s", buffer );
}
template< typename T1 >
void stringomatic( const char* format, T1 arg1 )
{
generic_format( format, formater< T1 >( arg1 ));
}
template< typename T1, typename T2 >
void stringomatic( const char* format, T1 arg1, T2 arg2 )
{
generic_format( format, formater< T1 >( arg1 ), formater< T2 >( arg2 ));
}
void test()
{
std::string foo( "foo" );
int i = 1;
stringomatic( "%1\n", foo );
stringomatic( "%1\n", i );
}
void foo1( const char* p, int b )
{
stringomatic( "P is %1 and b is %2\n", p, b );
}
void foo2( const char* p, int b )
{
printf( "P is %s and b is %d\n", p, b );
}
int main()
{
// test();
foo1( "p", 1 );
foo2( "p", 1 );
}
Context
- Re: [Libreoffice] message construction bloat ... (continued)
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.