glob2-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [glob2-devel] Refactoring


From: Bradley Arsenault
Subject: Re: [glob2-devel] Refactoring
Date: Tue, 2 May 2006 17:28:47 -0700

On 5/2/06, Sébastien <address@hidden> wrote:
Le Mardi 2 Mai 2006 08:31, Sébastien a écrit:
> Le Lundi 1 Mai 2006 21:19, Stéphane Magnenat a écrit:
> > Hi everyone,
> >
> > I'm very happy you're discussed my thoughts ;-)
> >
> > I suggested to use boost as I thought it was already used elsewhere. Now
> > if it's not the case then we can use another way.
> > The key requierment is that we want to be able to use ("toto %something
> > %somethingelse" arg1 arg2)ish syntax but with clean C++.
> >
> > Now, one solution is to use boost::format
> >
> > Another one would be to implement a Qt4-like arg in a subclass of
> > std::string. Here is my suggestion:
> >
> > class FormatableString : public std::string
> > {
> >     // level of argument, used for nested .arg()
> >     int argLevel;
> >
> >     FormatableString(const std::string &s) :
> >             std::string(s),
> >             argLevel(0)
> >     {
> >
> >     }
> >
> >     template <typename T>
> >     const FormatableString &arg(const T& value)
> >     {
> >             // transform value into std::string
> >             std::ostringstream oss;
> >             oss << value;
> >
> >             // from here is pseudo code
> >
> >             // find %argLevel in *this
> >             // if found,
> >                     // replace %argLevel by oss.str(), which is value 
transformed into
> > string
> >
> >             // end of pseuccode
> >
> >             // increment argLevel
> >             argLevel++,
> >
> >             // return reference to this so that .arg can proceed further
> >             return *this;
> >     }
> > };
> >
> > Opinions welcome
> >
> > Steph
>
> I'm ok
> the format string would be something like this "Hello %1, Welcome to %2"
> But we have to handle precision and radix for numbers (some are displayed
> in hexa)...
>
> > _______________________________________________
> > glob2-devel mailing list
> > address@hidden
> > http://lists.nongnu.org/mailman/listinfo/glob2-devel
>
> _______________________________________________
> glob2-devel mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/glob2-devel
I just started the implementation :

#include <cassert>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include "FormatableString.h"

void FormatableString::proceedReplace(const std::string &replacement)
{
        std::ostringstream search;
        search << "%" << this->argLevel;

        std::string::size_type pos = this->find(search.str(), 0);
        assert(pos != std::string::npos);
        this->replace(pos, search.str().length(), replacement);
        ++argLevel;
}

FormatableString &FormatableString::arg(int value, int base)
{
        std::ostringstream oss;
        oss << std::setbase(base);
        // transform value into std::string
        oss << value;

        proceedReplace(oss.str());

        // return reference to this so that .arg can proceed further
        return *this;
}
template <typename T> FormatableString &FormatableString::arg(const T& value)
{
        // transform value into std::string
        std::ostringstream oss;
        oss << value;

        proceedReplace(oss.str());

        // return reference to this so that .arg can proceed further
        return *this;
}


_______________________________________________
glob2-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/glob2-devel



If you absolutely insist on writing it yourself (which both me and Kai
exclaim is a very bad idea), try for a decent, convienent, easy to use
design:


class FormatArg
{
   public:
   explicit FormatArg(std::string& value);

   ///This function replaces the first found % symbol with `data`,
using an std::stringstream
   ///to perform the formatting. operator() might not be the best
choice, boost::format uses
   ///operator% which is quite consistent, either way works.
   template<typename T> FormatArg& operator()(const T& data);

   ///This function simply returns the string in its current state
   operator std::string();

   friend std::ostream& operator<<(std::ostream& ostr, const FormatArg& fa);

   private:
   std::string& value;
};

///Used for output operations
std::ostream& operator<<(std::ostream& ostr, const FormatArg& fa);

///Takes in a format specifies and returns a FormatArg object that will in turn
///Format the string as needed
FormatArg& format(const std::string& format_specifier);


//Heres an example of usage (changes can be made) with operator()

std::cout<<format("Hello %, how are you today? I have been running %:%
hours long.")("Bradley")(3)(5) << std::endl;


//Heres a more elegant example using operator%
std::cout<<format("Hello %, how are you today? I have been running %:%
hours long.") % "Bradley" % 3 % 5 <<std::endl;





Regardless of my suggestions, you should use boost::format instead. It
already handles all that printf handles, such as percision, and plenty
more. It has already been debugging, etc




reply via email to

[Prev in Thread] Current Thread [Next in Thread]