Découverte de boost.format

Yop, ça faisait longtemps que j’avais pas fait une ‘tite fiche programmation. Pas le temps d’implémenter ça dans mon projet, donc hop, un ‘tit poste pour y revenir un peu plus tard.

Boost.format donc. Mais qu’est-ce ? Me demanderez vous de votre petite voix émerveillée ! On va commencer par le commencement avant de répondre à la question : on connait tous (j’espère pour ceux qui ont fait du Cpp ) la STL (standard library) : toutes les classes bien pratiques du style std::string, std::fstream, etc. Et ben Boost, c’est la même chose, mais non standardisée (du moins pas encore, j’ai cru comprendre que certaines librairies de boost vont passer dans la STL dans un futur plus ou moins lointain) et complètement libre. Bref, ça ajoute pas mal de fonctionnalités au Cpp standard, et ça économise pas mal de temps sur pas mal de projets.

Jusqu’à présent, je l’utilisais juste pour ses regex dont j’abusais dans une petite classe de lecture / écriture de XML. Et v’là t’y pas que je tombe nez à nez avec la librairie boost.format. Vous connaissez les printf ? Vous connaissez donc les va_args, ces listes d’arguments variables que l’on utilisais en C/Cpp … Exemple :

class Foo
{
public:
    void SetFileName(const char * format, ...);
private:
    std::string   m_FileName;
};

// ailleurs :
Foo foo;
foo.SetName("%s/%s", g_UneGlobaleQuelconque,
                     "un_nom_de_fichier.txt");

C’est bien pratique. Sauf que ce petit “…” dans les arguments de Foo::SetFileName ben ça fait chier, passque pour écrire le code qui convertit tout ça en une chaine de charactère correctement formatée, et de manière sure, y’a pas mal de code et de fonction chelous à écrire. Exemple :

void Foo::SetFileName(const char * format, ...)
{
    int length = 0;
    va_list ap;
    char * fileName;

    // la tambouille qui recopie les
    // parametres là ou il faut, alloue
    // la chaine de caractere finale, etc.
    va_start(ap, format);
    len = _vscprintf(format, ap);
    fileName = new char [length + 1];
    _vsnprintf(fileName, length, format, ap);
    va_end(ap);
    fileName[length] = '\0';

    // on recopie dans la variable membre
    m_FileName.assign(fileName);

    // et on clean la chaine de caractere
    // temporaire.
    delete [] fileName;
}

Compliqué. Bah avec boost.format, ça donne ça :

class Foo
{
public:
    void SetFileName(const boost::format & format)
    {
        m_FileName = format.str();
    }
private:
    std::string   m_FileName;
};

// ailleurs :
Foo foo;
foo.SetName(boost::format("%1%/%2%") %
                g_UneGlobaleQuelconque %
                "un_nom_de_fichier.txt");

Roh pitain ! Truc de ouf sa mère ! Hum. Bon, la syntaxe d’appel change un peu : il n’y a plus de %d pour les entiers, %s pour les strings, etc. Juste un %x% où x représente le numéro du paramètre à mettre à la place. Par contre, au niveau de la gestion du résultat … vous avouerez qu’il n’y a aucune comparaison possible : boost.format est 10 fois plus simple à utiliser.

Bon, j’ai pas vraiment pris le temps de regarder toutes les subtilités de cette librairie, donc pour de plus amples informations, allez voir sur le site (click click)