<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coder-Studio &#187; C</title>
	<atom:link href="http://www.coder-studio.com/blog/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 31 Mar 2010 00:00:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tutoriel Boost Graph Library</title>
		<link>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/</link>
		<comments>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 01:06:58 +0000</pubDate>
		<dc:creator>Calvin1602</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[graphes]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=429</guid>
		<description><![CDATA[Boost, c'est le bien, et la BGL ne fait pas exception à la règle. BGL permet d'utiliser des algorithmes de graphes précodés en l'adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.
C'est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble [...]
Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable.]]></description>
			<content:encoded><![CDATA[<p>Boost, c&#8217;est le bien, et la BGL ne fait pas exception à la règle. BGL permet d&#8217;utiliser des algorithmes de graphes précodés en l&#8217;adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.<br />
C&#8217;est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble :<br />
<span id="more-429"></span></p>
<ul>
<li>Elle est très peu connexe. Par exemple, il y a un unique lien vers la table des matières.</li>
<li>Elle est peu explicite. Par exemple, dans l&#8217;interface de l&#8217;algorithme de dijkstra, on peut trouver un bgl_named_parameters. Il faut se lever de bonne heure pour trouver ce que c&#8217;est.</li>
<li>Les exemples sont rares et peu explicites. Le seul exemple de l&#8217;algorithme A* est peu commenté (et encore moins aux parties les plus dures), démontre deux autres features qui n&#8217;ont rien à voir, utilise l&#8217;interface obsolète et non recommandée de la lib, et complique le tout avec une autre couche de templates totalement inutile pour un tuto qui se veut simple.</li>
</ul>
<p>Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable. Tous les membres du namespace boost seront préfixés par boost:: afin de savoir qu&#8217;est-ce qui est à nous et qu&#8217;est-ce qui est à Boost.</p>
<p>Il est basé sur le cas suivant : on a un graphe de waypoints, et on veut utiliser l&#8217;algorithme A* (qui utilise une bonne partie des concepts importants de la lib). Dans un premier temps, dans un souci de simplicité, on va utiliser une heuristique par défaut, qui rend toujours zéro. On verra par la suite comment l&#8217;adapter.</p>
<p>On va avoir besoin de deux headers boost:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code1'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4291"><td class="code" id="p429code1"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;boost/graph/adjacency_list.hpp&gt;</span>
<span style="color: #339900;">#include &lt;boost/graph/astar_search.hpp&gt;</span></pre></td></tr></table></div>

<p>On va maintenant définir les structures nécessaires à définir notre graphe :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code2'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4292"><td class="code" id="p429code2"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Un waypoint</span>
<span style="color: #0000ff;">struct</span> WayPoint<span style="color: #008000;">&#123;</span>
    Vector3f pos<span style="color: #008080;">;</span>
    <span style="color: #666666;">// et éventuellement d'autres informations (crouch, hide, camp, ...)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Une liaison entre deux waypoints</span>
<span style="color: #0000ff;">struct</span> WayPointConnection<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">float</span> dist<span style="color: #008080;">;</span>
    <span style="color: #666666;">// idem</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va maintenant déclarer le type de notre graphe. On va utiliser une adjacency_list, qui est un peu un graphe à tout faire. Ce n&#8217;est pas le plus optimisé dans tous les cas, mais il est très versatile et convient très bien ici.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code3'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4293"><td class="code" id="p429code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">adjacency_list</span><span style="color: #000080;">&lt;</span>  <span style="color: #666666;">// adjacency_list est un template qui dépend de :</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">listS</span>,               <span style="color: #666666;">//  le conteneur utilisé pour les arcs partant d'un sommet. Ici, std::list.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">vecS</span>,                <span style="color: #666666;">//  le conteneur utilisé pour contenir tous les sommets du graphe. Ici, std::vector.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">undirectedS</span>,         <span style="color: #666666;">//  le type des arcs. Pourrait être boost::directedS.</span>
    WayPoint,                   <span style="color: #666666;">//  le type qui décrit un sommet.</span>
    WayPointConnection          <span style="color: #666666;">//  le type qui décrit un arc.</span>
<span style="color: #000080;">&gt;</span> WayPointGraph<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Les deux premiers paramètres influent grandement sur l&#8217;organisation mémoire et les performances de graphe. Selon les applications, une liste, un vecteur, un set, une map, &#8230; sera plus approprié. Pour plus d&#8217;information, voir <a href="http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/using_adjacency_list.html#sec:choosing-graph-type">la doc</a>.</p>
<p>On déclare aussi des raccourcis pour les IDs de sommets et d&#8217;arcs (en fait, ce sont des unsigned int)</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code4'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4294"><td class="code" id="p429code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">vertex_descriptor</span> WayPointID<span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">edge_descriptor</span>   WayPointConnectionID<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va pouvoir instancier notre graphe.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code5'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4295"><td class="code" id="p429code5"><pre class="cpp" style="font-family:monospace;">WayPointGraph graphe<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On commence par rajouter tous les sommets :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code6'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4296"><td class="code" id="p429code6"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets S<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    WayPointID wpID <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_vertex</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// wp est l'indice d'un nouveau sommet qui a été ajouté dans graphe</span>
    graphe<span style="color: #008000;">&#91;</span>wpID<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span> <span style="color: #000080;">=</span> la position du sommet S    <span style="color: #666666;">// graphe[ un WayPointID ] est un WayPoint. On peut donc régler sa position de cette manière.</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Maintenant, on peut les relier par des arcs. Là, c&#8217;est à vous de savoir où vont les arcs, boost ne va pas le deviner tout seul&#8230;</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code7'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4297"><td class="code" id="p429code7"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// petit changement de notation, dans boost un arc est souvent décrit entre deux sommets u et v.</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous les voisins V de U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// C'est à vous de savoir quels sont les voisins de U.</span>
&nbsp;
        WayPointID u <span style="color: #000080;">=</span> indice de U<span style="color: #008080;">;</span> <span style="color: #666666;">// soit c'est le int du for(), soit il faut y accéder via un autre vector. Cf les notes plus bas.</span>
        WayPointID v <span style="color: #000080;">=</span> indice de V<span style="color: #008080;">;</span>
&nbsp;
        WayPointConnectionID edge<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">bool</span> ok<span style="color: #008080;">;</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">tie</span><span style="color: #008000;">&#40;</span>edge, ok<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_edge</span><span style="color: #008000;">&#40;</span>u,v, graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// boost::add_edge renvoie une std::pai&gt;WayPointConnectionID,bool&gt;. C'est compliqué à écrire, alors on laisse boost::tie le faire pour nous.</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>ok<span style="color: #008000;">&#41;</span>  <span style="color: #666666;">// Si le graphe a bel et bien été ajouté ( pas de doublon, par exemple, sauf si spécifié dans le typedef de WayPointGraph )</span>
        graphe<span style="color: #008000;">&#91;</span>edge<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">dist</span> <span style="color: #000080;">=</span> Distance<span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span>, graphe<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Longueur d'un arc = distance euclidienne entre les deux sommets u et v.</span>
&nbsp;
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Plusieurs choses sont à remarquer :</p>
<ul>
<li>Personnellement, j&#8217;ai utilisé le fait que WayPointID est en fait un int et que dans mon double for(), j&#8217;utilise un int pour accéder au waypoint. C&#8217;est pas très propre, mais ça évite l&#8217;utilisation d&#8217;un vector en plus.</li>
<li>graphe[edge] ( edge étant un WayPointConnectionID ) est un WayPointConnection, alors que graphe[u] (u étant un WaypointID) est un WayPoint. On peut donc accéder directement à leurs membres.</li>
<li>Cette dernière remarque est très importante. Cette syntaxe est très appréciable, elle évite d&#8217;utiliser les incompréhensibles boost::property_map, elle oblige seulement à avoir un compilateur récent. GCC et Visual s&#8217;en sortent très bien.</li>
</ul>
<p>Pour information, mon code à moi ressemble à ça :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code8'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4298"><td class="code" id="p429code8"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>indices.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">/</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    ConnectiviteTriangle connectivity<span style="color: #008080;">;</span>
    fillconnectivityinfo<span style="color: #008000;">&#40;</span>i, connectivity, indices<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> c<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> c<span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> c<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        TriangleDescriptor u <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span>
        TriangleDescriptor v <span style="color: #000080;">=</span> connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>La syntaxe est moyennement cool, mais j&#8217;espère que ça vous aidera à mieux comprendre.</p>
<p>Ok, donc maintenant notre graphe a des sommets et des arcs. On va pouvoir faire du pathfinding !</p>
<p>Pour ça, on va avoir besoin de quelques structures :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code9'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4299"><td class="code" id="p429code9"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Une instance de cette structure sera lancée en exception quand on aura trouvé un chemin</span>
<span style="color: #0000ff;">struct</span> found_goal <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Le visiteur, dont le but est de définir une fonction examine_vertex qui dit si on est arrivé au but.</span>
<span style="color: #666666;">// Le but est spécifié via le constructeur.</span>
<span style="color: #0000ff;">class</span> astar_goal_visitor <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">default_astar_visitor</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    astar_goal_visitor<span style="color: #008000;">&#40;</span>WayPointID goal<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">void</span> examine_vertex<span style="color: #008000;">&#40;</span>WayPointID u, <span style="color: #0000ff;">const</span> Graph <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> g<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Le const est important.</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>u <span style="color: #000080;">==</span> m_goal<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">throw</span> found_goal<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// On sort en lancant une exception. C'est moche mais c'est comme ça.</span>
        <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    WayPointID m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Il faut maintenant trouver notre point de départ et notre point d&#8217;arrivée. C&#8217;est votre problème, mais il faut arriver à quelque chose du style :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code10'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42910"><td class="code" id="p429code10"><pre class="cpp" style="font-family:monospace;">TriangleDescriptor goal <span style="color: #000080;">=</span> ...
<span style="color: #007788;">TriangleDescriptor</span> start <span style="color: #000080;">=</span> ...</pre></td></tr></table></div>

<p>Ok, on y va :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code11'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42911"><td class="code" id="p429code11"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Deux vecteurs qui vont servir à sauvegarder le résultat de la recherche</span>
vector<span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> p<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les prédécesseurs</span>
vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span>      d<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les distances</span>
&nbsp;
<span style="color: #0000ff;">try</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Encore une fois, la découverte d'un chemin est signalée par une exception, donc il faut un try/catch.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_search</span>
    <span style="color: #008000;">&#40;</span>
        graphe, <span style="color: #666666;">// notre graphe</span>
        start,  <span style="color: #666666;">// notre point de départ</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span><span style="color: #000080;">&lt;</span>NavMeshGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #666666;">// Une heuristique bidon qui renvoie toujours 0</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">predecessor_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">distance_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>d<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">visitor</span><span style="color: #008000;">&#40;</span>astar_goal_visitor<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">weight_map</span><span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">get</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>WayPointConnection<span style="color: #008080;">::</span><span style="color: #007788;">dist</span>, graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #666666;">// Voir plus bas</span>
    <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>found_goal fg<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// On a trouvé un chemin</span>
    <span style="color: #666666;">// On suit le chemin trouvé dans le sens inverse</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> shortest_path<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>WayPointID v <span style="color: #000080;">=</span> goal<span style="color: #008080;">;;</span> v <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        shortest_path.<span style="color: #007788;">push_front</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> v<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">// et on l'affiche.</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> spi <span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">++</span>spi<span style="color: #008080;">;</span> spi <span style="color: #000040;">!</span><span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>spi<span style="color: #008000;">&#41;</span>
        Log<span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>spi<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    Log<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Total travel time: &quot;</span> , d<span style="color: #008000;">&#91;</span>goal<span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Remarque sur la ligne bizarre:</p>
<ul>
- Ce ne sont pas des virgules, ce sont des points ! Il s&#8217;agit d&#8217;un seul objet auquel on rajoute plein de propriétés. Cette syntaxe est par exemple utilisée dans la création d&#8217;interfaces graphiques : monmenu.addoption(&laquo;&nbsp;option1&#8243;).addoption(&laquo;&nbsp;option2&#8243;) etc<br />
- A* a besoin de ces quatre propriétés : une map de prédécesseurs, une map de distances, une map de poids, et un visiteur.<br />
- La map de poids est intrisèque au graphe : elle est stockée dans le champ dist des arcs. Mais Boost ne peut pas deviner tout seul que c&#8217;est cette variable qu&#8217;il faut lire, donc on le lui dit avec boost::get(&amp;WayPointConnection::dist, graphe)</p>
<li>Le visiteur est initialisé avec le goal pour pouvoir lancer son exception si il y a réussite.</li>
</ul>
<p>Vous avez économisé 4 heures de prise de tête avec la doc de BGL, autant d&#8217;implémentation de l&#8217;A* si vous l&#8217;aviez codé vous même, et autant de débug que vous n&#8217;aurez jamais à faire : un des grands intérêts des templates, c&#8217;est que comme en OCaml, quand ça compile, ça marche (souvent) ^^.</p>
<p>Voyons maintenant comment améliorer un peu notre heuristique : pour l&#8217;instant, on n&#8217;a fait qu&#8217;un parcours brutal de l&#8217;arbre, ça ne valait pas trop le coup.<br />
Cela va bien sûr passer par une nouvelle structure :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code12'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42912"><td class="code" id="p429code12"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> distance_heuristic <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span> <span style="color: #000080;">&lt;</span>WayPointGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// De la même manière que tout à l'heure, on passe les données dont il aura besoin dans son foncteur à la construction.</span>
    distance_heuristic<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> l, WayPointID goal<span style="color: #008000;">&#41;</span>
    <span style="color: #008080;">:</span> m_graph<span style="color: #008000;">&#40;</span>l<span style="color: #008000;">&#41;</span>, m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">float</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>WayPointID u<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> U <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> V <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>m_goal<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dx <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dy <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">sqrt</span><span style="color: #008000;">&#40;</span>dx <span style="color: #000040;">*</span> dx <span style="color: #000040;">+</span> dy <span style="color: #000040;">*</span> dy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> m_graph<span style="color: #008080;">;</span>
    TriangleDescriptor m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>m_graph peut être remplacé ( en changeant le constructeur et l&#8217;opérateur ) par n&#8217;importe quoi qui vous permette d&#8217;obtenir la position d&#8217;un vertex à partir de son identifiant. Cela peut être comme ici le graphe lui-même, mais aussi les données à partir duquel il a été construit, etc.</p>
<p>Il suffit maintenant de remplacer boost::astar_heuristic<WayPointGraph, float>() par distance_heuristic(graphe, goal) dans l&#8217;appel au A*.</p>
<p>Oh, et au fait : les waypoints ça pue, utilisez des navmeshes.</p>
<p><a href="http://www.coder-studio.com/forum2/viewtopic.php?id=1392">Discussion sur le forum</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Préprocesseur et énumérations : la suite.</title>
		<link>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/</link>
		<comments>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 20:34:09 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=393</guid>
		<description><![CDATA[Cet article fait suite à mon premier article intitulé &#171;&#160;Faire un peu joujou avec le préprocesseur&#160;&#187;
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).
Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création
d&#8217;un opérateur &#171;&#160;]]></description>
			<content:encoded><![CDATA[<p>Cet article fait suite à mon premier article intitulé &laquo;&nbsp;Faire un peu joujou avec le préprocesseur&nbsp;&raquo;<br />
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).</p>
<p>Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création<br />
d&#8217;un opérateur &laquo;&nbsp;<<" pour iostream, capable d'afficher le nom d'une énumération.</p>
<p><span id="more-393"></span></p>
<p>Voici le code :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code24'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39324"><td class="code" id="p393code24"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_N(nb_vals, __VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(nb_vals, enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code25'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39325"><td class="code" id="p393code25"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Le plus gros problème de ce système est le fait que l&#8217;on soit obligés de donner le nombre de valeurs de l&#8217;énumération<br />
lors de l&#8217;utilisation de la macro ENUMERATE.</p>
<p>Ce qui nous oblige à spécifier ce numéro, c&#8217;est la nécessiter de &laquo;&nbsp;choisir&nbsp;&raquo; la bonne macro parmi ENUM_CASE_1, ENUM_CASE_2, &#8230;, ENUM_CASE_10.</p>
<p>Se passer de ce nombre, c&#8217;est effectuer l&#8217; &laquo;&nbsp;appel récursif&nbsp;&raquo; jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument à traiter dans la<br />
&laquo;&nbsp;liste&nbsp;&raquo; __VA_ARGS__.</p>
<p>Que se passe-t-il si l&#8217;on supprime ce nombre et que l&#8217;on remplace l&#8217;appel à ENUM_CASE_N par la version qui gère le plus d&#8217;arguments<br />
(ici ENUM_CASE_10, donc) ?</p>
<p>Version remaniée :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code26'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39326"><td class="code" id="p393code26"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_10(__VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code27'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39327"><td class="code" id="p393code27"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// test.cpp</span>
&nbsp;
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Après un appel au préprocesseur par &laquo;&nbsp;cpp test.cpp&nbsp;&raquo;, voici ce qu&#8217;il nous affiche (remis en forme pour être lisible et<br />
en enlevant les lignes commençant par un #, sans importance) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code28'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39328"><td class="code" id="p393code28"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">enum</span> MonEnumeration <span style="color: #008000;">&#123;</span> E_VAL_1, E_VAL_2, E_VAL_3 <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_3<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_3&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Vous voyez le problème : on a des &laquo;&nbsp;case :&nbsp;&raquo; à partir du stade où il n&#8217;y a plus d&#8217;argument. Il faut donc remplacer<br />
chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; (correspondant à ce que génère ENUM_CASE_1) par quelque chose qui puisse faire un test d&#8217;égalité<br />
entre &laquo;&nbsp;e&nbsp;&raquo; et &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc, mais qui puisse aussi compiler et ne rien faire lorsqu&#8217;en lieu et place<br />
de &laquo;&nbsp;E_VAL_XXX&nbsp;&raquo;, il n&#8217;y a rien.</p>
<p>Là, on pense à la surcharge de fonction ! En effet, si l&#8217;on a une fonction surchargée ainsi :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code29'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39329"><td class="code" id="p393code29"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blabla</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blublu</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>on peut obtenir un comportement différent selon que l&#8217;on passe ou pas quelque chose en argument à la fonction !<br />
Il suffirait de remplacer chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; par un test d&#8217;égalité qui aurait cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code30'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39330"><td class="code" id="p393code30"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #008000;">&#40;</span>e, E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>et le tour est joué !</p>
<p>Mais attendez, vous ne voyez pas un problème ? Si, si : contrairement à la fonction f() de l&#8217;exemple, ce &laquo;&nbsp;TestEgalite&nbsp;&raquo;<br />
a 2 arguments. Si l&#8217;on remplace &laquo;&nbsp;E_VAL_1&#8243; par du vide, on obtient un &laquo;&nbsp;if(TestEgalite(e, )) {blabla;}&nbsp;&raquo; : ça ne marche pas !</p>
<p>Le problème reste donc entier&#8230;<br />
Oui, pour ceux qui se demandent, cette partie de l&#8217;article n&#8217;apporte rien à la solution, c&#8217;est juste la démarche que j&#8217;ai<br />
eue : vous pouvez vous dire que ça ne sert à rien, je ne vous le reprocherai pas, mais maintenant c&#8217;est trop tard, vous<br />
l&#8217;avez lu :p</p>
<p>On pourrait se poser le problème ainsi : comment, à partir d&#8217;une fonction à 2 arguments, en faire 2 fonctions à 1 argument ?<br />
En effet, si l&#8217;on arrive à en faire 2 fonctions à 1 argument, alors le problème serait réglé <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Si je ne m&#8217;abuse, il<br />
s&#8217;agit de la &laquo;&nbsp;curryfication&nbsp;&raquo;, que l&#8217;on trouve en programmation fonctionnelle et en lambda-calcul <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Peut-être est-ce possible, je n&#8217;ai pas exploré cette possibilité. Il ne m&#8217;étonnerait pas que cela soit possible grâce à des<br />
foncteurs, i.e. une classe dont un surcharge l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;. On peut ainsi se retrouver avec une construction de la forme<br />
&laquo;&nbsp;MaClasse(arg1)(arg2)&nbsp;&raquo;, i.e. un appel au constructeur suivi d&#8217;un appel à l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;.</p>
<p>En fait, à mon avis, c&#8217;est une solution possible, je garderai peut-être pour la suite, dans un hypothétique futur article <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Quoi qu&#8217;il en soit, pour en revenir au problème : on peut aussi se le poser ainsi : est-on obligés de traiter les cas où<br />
le préprocesseur ne met rien, en lieu et place de nos &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc ? Dit encore autrement, ne peut-on pas mettre<br />
quelque chose d&#8217;autre à la place ? Qu&#8217;est-ce qui nous arrangerait alors ?</p>
<p>Hmm, voyons voir, remplacer le vide par quelque chose que l&#8217;on pourrait tester lors de la compilation&#8230;<br />
Il s&#8217;agit bien de méta-programmation. Or, en méta-programmation : les 2 outils principaux que le C++ met à notre disposition<br />
sont les macros et les templates.</p>
<p>Eurêka !</p>
<p>On peut &laquo;&nbsp;surcharger&nbsp;&raquo; une fonction template qui s&#8217;occupera de faire le test d&#8217;égalité !<br />
On écrit alors les tests d&#8217;égalité comme ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code31'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39331"><td class="code" id="p393code31"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_1<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_2<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
...
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>On déclare alors TestEgalite sous cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code32'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39332"><td class="code" id="p393code32"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span>MonEnumeration val<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> e <span style="color: #000080;">==</span> val<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Et le tour est joué !</p>
<p>Bon, maintenant, pour faire plus pro, en renommant ça en anglais et en préfixant par le nom de l&#8217;énumération<br />
(histoire que l&#8217;on n&#8217;ait pas de conflit s&#8217;il y a 2 énumérations différentes, au cas où), et en remettant tout<br />
ensemble, cela donne ceci :</p>
<p>Version finale :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code33'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39333"><td class="code" id="p393code33"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(EnumType, ...)	\
	enum EnumType { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(EnumType, val, ...)	\
	if(EnumType ## _EnumIsEqual&lt;val&gt;(e)) {os &lt;&lt; #val; break;}</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_1(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_3(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_2(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_4(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_3(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_5(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_4(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_6(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_5(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_7(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_6(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_8(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_7(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_9(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_8(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_10(EnumType, val, ...)	ENUM_CASE_1(EnumType, val) ENUM_CASE_9(EnumType, __VA_ARGS__, void)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(EnumType, ...)	\
	template &lt;EnumType val&gt;				\
	inline bool EnumType ## _EnumIsEqual(const EnumType&amp; e) {	\
		return e == val;										\
	}															\
																\
	template &lt;class T&gt;											\
	inline bool EnumType ## _EnumIsEqual(const EnumType&amp; e) {	\
		return false;											\
	}															\
																\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const EnumType&amp; e) {	\
		do {																\
			ENUM_CASE_10(EnumType, __VA_ARGS__, void)								\
		} while(0);											\
		return os;											\
	}</span>
&nbsp;
<span style="color: #339900;">#define ENUMERATE(EnumType, ...)		\
	MAKE_ENUM(EnumType, __VA_ARGS__)	\
	MAKE_OPERATOR(EnumType, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code34'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p39334"><td class="code" id="p393code34"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Voilà pour cette partie <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ceci dit, un problème est résolu, mais il en reste d&#8217;autres, notamment :<br />
- ça doit toujours aussi mal passer auprès des systèmes d&#8217;auto-complétion (enfin, j&#8217;ai pas testé sur Visual Assist<br />
  ou Eclipse à vrai dire&#8230;)<br />
- on ne peut toujours pas attribuer de valeur numérique manuellement à un symbole de l&#8217;énumération</p>
<p>Il pourrait aussi être intéressant d&#8217;associer une autre chaîne de caractères, voire toute autre valeur, à un symbole de<br />
l&#8217;énumération&#8230;<br />
Tout comme il serait intéressant d&#8217;explorer une solution à base de pseudo-curryfication plutôt que de templates, voire, qui<br />
sait, une solution entièrement à base de templates. A ce sujet, un article très intéressant est disponible ici pour les<br />
curieux : http://www.codeguru.com/cpp/cpp/cpp_mfc/templates/article.php/c4137</p>
<p>Ce sera tout pour cette fois !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Faire un peu joujou avec le préprocesseur&#8230;</title>
		<link>http://www.coder-studio.com/blog/preproc/</link>
		<comments>http://www.coder-studio.com/blog/preproc/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 18:53:54 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=371</guid>
		<description><![CDATA[Ça faisait un bail que je n'écrivais pas sur Coder-Studio...
Chose réparée :)

Du 17 au 19 avril 2009, a eu lieu la finale de Cod'INSA, un concours de programmation inter-INSA,
qui s'est déroulée à l'INSA de Toulouse (plus d'infos sur http://codinsa.insa-lyon.fr pour les intéressés).
Faisant partie des organisateurs, j'ai eu à faire l'interfaçage C++/Java (oui parce qu'il y en a qui veulent
participer en Java...allez comprendre :p [/troll]). J'y ai découvert les joies de GCJ et de CNI, ce qui
pourra peut-être être l'objet d'un autre article, selon ma motivation...

Bref, tout ça pour dire qu'il m'a fallu interfacer une librairie écrite en C avec du Java, et qu'il a fallu
automatiser un peu le boulot pour la partie concernant les énumérations.

Dans cet article, je vais illustrer une méthode pour faciliter l'affichage des valeurs des énumérations.
En gros, le but, c'est que si l'on a :
<pre lang="cpp">
MonEnumeration e = E_VAL_1;
std::cout << e << std::endl;
</pre>

il s'affiche alors à l'écran "E_VAL_1".]]></description>
			<content:encoded><![CDATA[<p>Ça faisait un bail que je n&#8217;écrivais pas sur Coder-Studio&#8230;<br />
Chose réparée <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Du 17 au 19 avril 2009, a eu lieu la finale de Cod&#8217;INSA, un concours de programmation inter-INSA,<br />
qui s&#8217;est déroulée à l&#8217;INSA de Toulouse (plus d&#8217;infos sur http://codinsa.insa-lyon.fr pour les intéressés).<br />
Faisant partie des organisateurs, j&#8217;ai eu à faire l&#8217;interfaçage C++/Java (oui parce qu&#8217;il y en a qui veulent<br />
participer en Java&#8230;allez comprendre :p [/troll]). J&#8217;y ai découvert les joies de GCJ et de CNI, ce qui<br />
pourra peut-être être l&#8217;objet d&#8217;un autre article, selon ma motivation&#8230;</p>
<p>Bref, tout ça pour dire qu&#8217;il m&#8217;a fallu interfacer une librairie écrite en C avec du Java, et qu&#8217;il a fallu<br />
automatiser un peu le boulot pour la partie concernant les énumérations.</p>
<p>Dans cet article, je vais illustrer une méthode pour faciliter l&#8217;affichage des valeurs des énumérations.<br />
En gros, le but, c&#8217;est que si l&#8217;on a :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code35'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37135"><td class="code" id="p371code35"><pre class="cpp" style="font-family:monospace;">MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>il s&#8217;affiche alors à l&#8217;écran &laquo;&nbsp;E_VAL_1&#8243;.</p>
<p><span id="more-371"></span></p>
<p>La version non automatisée consiste en l&#8217;écriture d&#8217;une surcharge de l&#8217;opérateur &laquo;&nbsp;<<". Programme de démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code36'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37136"><td class="code" id="p371code36"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">enum</span> MonEnumeration
<span style="color: #008000;">&#123;</span>
	E_VAL_1,
	E_VAL_2
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Ce programme affiche bien &laquo;&nbsp;E_VAL_1&#8243; à l&#8217;écran.</p>
<p>Mais c&#8217;est tout de même bien contraignant : la duplication des informations est évidente : entre la<br />
déclaration de l&#8217;énumération et l&#8217;opérateur &laquo;&nbsp;<<", "E_VAL_1" est écrit 3 fois ! C'est évidemment source<br />
d'erreurs (le copier-coller n'est pas le meilleur ami du programmeur, loin s'en faut...), particulièrement<br />
lorsque l'on veut rajouter de nouvelles valeurs à l'énumération. Et puis c'est tout simplement pénible<br />
de devoir maintenir l'énumération et l'opérateur.<br />
Bref, c'est moche, peut mieux faire.</p>
<p>C'est là qu'arrive le préprocesseur.</p>
<p>A partir de là, je suppose que vous utilisez GCC (ou MinGW/Cygwin sous Windows).</p>
<p>Nous allons en particulier nous baser sur 2 opérateurs spéciaux du préprocesseur, qui ne sont pas très<br />
connus : # et ##.</p>
<p>Commençons par # : il permet de rajouter des guillemets autour de l'argument d'une macro.</p>
<p>Démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code37'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37137"><td class="code" id="p371code37"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define STRINGIFY(val) #val</span>
&nbsp;
STRINGIFY<span style="color: #008000;">&#40;</span>pouet<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>Supposons que vous ayez enregistré cela dans &laquo;&nbsp;pouet.h&nbsp;&raquo; : passez un coup de préprocesseur : &laquo;&nbsp;cpp pouet.h&nbsp;&raquo;<br />
(ou bien &laquo;&nbsp;g++ -E pouet.h&nbsp;&raquo;, ça revient au même).</p>
<p>Résultat affiché :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code38'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37138"><td class="code" id="p371code38"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
&nbsp;
&quot;pouet&quot;</pre></td></tr></table></div>

<p>Bon, déjà, ça c&#8217;est intéressant <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  On remarque que cpp écrit des lignes commençant par un #, que le compilateur<br />
qui passe derrière doit probablement interpréter pour les messages d&#8217;erreurs afin d&#8217;indiquer la ligne de l&#8217;erreur.</p>
<p>Passons à la suite : on voudrait une macro qui permette d&#8217;automatiser la création de l&#8217;opérateur &laquo;&nbsp;<<" pour<br />
l'affichage de la valeur de notre énumération.<br />
Essayons d'abord en supposant que notre énumération ne puisse contenir qu'une seule valeur :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code39'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37139"><td class="code" id="p371code39"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, val)	\
	enum enum_name {	\
		val			\
	};</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, val)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			case val:	\
				os &lt;&lt; #val;	\
				break;	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, val)	\
	MAKE_ENUM(enum_name, val)	\
	MAKE_OPERATOR(enum_name, val)</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On a donc une macro MAKE_ENUM qui s&#8217;occupe de déclarer l&#8217;énumération et une macro MAKE_OPERATOR qui s&#8217;occupe<br />
de définir l&#8217;operateur &laquo;&nbsp;<<". Notez le "inline" qui sert à éviter tout problème de linkage (si le même fichier .h,<br />
qui décrit l'énumération et l'opérateur, est inclus dans 2 .cpp différents, on se retrouve avec l'opérateur défini 2<br />
fois, et couic !).</p>
<p>Cool, ça marche ! (en même temps c'est un tuto...)</p>
<p>Maintenant, on peut arrêter de contourner la difficulté et s'attaquer au vrai problème : comment gérer le fait<br />
qu'une énumération n'ai pas 1, 2, ou 3 valeurs, mais un nombre variable ??</p>
<p>C'est là qu'arrive une autre astuce du préprocesseur : la macro __VA_ARGS__.</p>
<p>Démonstration, dans notre pouet.h :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code40'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37140"><td class="code" id="p371code40"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MA_MACRO(...) __VA_ARGS__</span>
MA_MACRO<span style="color: #008000;">&#40;</span>a, b, c<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>cpp pouet.h donne :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code41'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37141"><td class="code" id="p371code41"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
a, b, c</pre></td></tr></table></div>

<p>Pratique, quand on veut des macros avec un nombre variable d&#8217;arguments&#8230;</p>
<p>On peut dores et déjà remplacer MAKE_ENUM par une version capable de gérer un nombre variable d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code42'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37142"><td class="code" id="p371code42"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span></pre></td></tr></table></div>

<p>Ça, c&#8217;est fait. Maintenant, reste le problème de MAKE_OPERATOR&#8230;</p>
<p>Si l&#8217;on analyse le problème, on voit que l&#8217;on a 3 parties :</p>
<p>- une introduction :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code43'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37143"><td class="code" id="p371code43"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span></pre></td></tr></table></div>

<p>- une partie qui se répète :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code44'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37144"><td class="code" id="p371code44"><pre class="cpp" style="font-family:monospace;">		<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>
			os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;</span>
			<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>- une conclusion :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code45'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37145"><td class="code" id="p371code45"><pre class="cpp" style="font-family:monospace;">		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Il s&#8217;agit donc, à partir d&#8217;une liste variable d&#8217;arguments, de répéter plusieurs fois la partie centrale pour<br />
chaque argument &laquo;&nbsp;val&nbsp;&raquo;. C&#8217;est là que j&#8217;ai pensé à ces vieux cours de Caml, où pour traiter une liste, on écrivait<br />
une fonction récursive, qui décomposait la liste en t::q (pour tête et queue), la tête étant le 1er élément, et la<br />
queue tout le reste. Désolé pour ceux qui n&#8217;ont pas fait de Caml :p</p>
<p>Pour revenir à notre préprocesseur, cela se traduirait par une macro qui prend en argument quelque chose de la forme :<br />
#define MACRO(a, &#8230;) et qui ensuite s&#8217;appellerait récursivement jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument.</p>
<p>Malheureusement, la récursivité, en préprocesseur ça n&#8217;existe pas, ou alors j&#8217;ai pas trouvé comment&#8230;</p>
<p>Il va donc falloir trouver une parade : il s&#8217;agira d&#8217;écrire une version de la macro pour chaque appel récursif, i.e.<br />
pour chaque nombre d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code46'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37146"><td class="code" id="p371code46"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le problème n&#8217;est toujours pas totalement résolu : encore faut-il choisir la bonne macro à utiliser&#8230;</p>
<p>C&#8217;est là qu&#8217;arrive l&#8217;opérateur ## du préprocesseur <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Celui-ci permet de concaténer des symboles.</p>
<p>Exemple (dans pouet.h) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code47'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37147"><td class="code" id="p371code47"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define CONCAT(a, b) a ## b</span>
CONCAT<span style="color: #008000;">&#40;</span>foo, bar<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>&laquo;&nbsp;cpp pouet.h&nbsp;&raquo; affiche cette fois :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code48'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37148"><td class="code" id="p371code48"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
foobar</pre></td></tr></table></div>

<p>Cela va nous servir à choisir la bonne macro à utiliser :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code49'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37149"><td class="code" id="p371code49"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le gros inconvénient est bien sûr qu&#8217;il nous faut préciser le nombre de valeurs de l&#8217;énumération :/</p>
<p>Il semble que l&#8217;on ait fait le tour. Voici donc la version finale de tout ça, séparée dans un .h générique<br />
et un .cpp d&#8217;exemple :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code50'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37150"><td class="code" id="p371code50"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\
	enum enum_name { __VA_ARGS__ };</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\
	case val:	\
		os &lt;&lt; #val;	\
		break;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\
	inline std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const enum_name&amp; e)	{\
		switch(e) {	\
			ENUM_CASE_N(nb_vals, __VA_ARGS__)	\
		}	\
		return os;	\
	}</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\
	MAKE_ENUM(enum_name, __VA_ARGS__)	\
	MAKE_OPERATOR(nb_vals, enum_name, __VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code51'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p37151"><td class="code" id="p371code51"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p><strong>Conclusion</strong></p>
<p>Au final, cette méthode présente l&#8217;avantage d&#8217;éviter la duplication de code, et tous les ennuis qui vont avec.<br />
Il reste cependant plusieurs inconvénients non négligeables :<br />
- On est obligés de préciser le nombre de valeurs de l&#8217;énumération<br />
- On est limités dans le nombre de valeurs que l&#8217;on peut définir par le nombre de macros que l&#8217;on a définis dans Enumerate.h<br />
  A la limite, si l&#8217;on a besoin de plus de valeurs, il suffit de les rajouter, c&#8217;est pas bien grave ^^<br />
- Pour la plupart des IDE, je pense qu&#8217;un tel système aboutit à un type &laquo;&nbsp;MonEnumeration&nbsp;&raquo;, ainsi que les valeurs définies,<br />
  qui sont inconnus. Ça peut être un problème&#8230;<br />
- En déclarant ses énumérations de la sorte, on ne peut pas préciser de valeur numérique pour chaque valeur possible de<br />
  l&#8217;énumération.</p>
<p>La méthode a ses limites, et je me demande s&#8217;il n&#8217;y aurait pas moyen d&#8217;aller au-delà en utilisant des templates&#8230;<br />
Par ailleurs, ce petit article sur le préprocesseur ne fait aucune mention de Boost::Preprocessor, qui, selon Arnaud,<br />
est incroyable à voir&#8230;<br />
Je serais curieux de voir s&#8217;il pourrait apporter un élément de réponse au problème ^^</p>
<p>Ce sera tout !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preproc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Introduction à wxWidgets</title>
		<link>http://www.coder-studio.com/blog/introduction-a-wxwidgets/</link>
		<comments>http://www.coder-studio.com/blog/introduction-a-wxwidgets/#comments</comments>
		<pubDate>Mon, 08 Aug 2005 16:47:29 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[wxWidgets]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=123</guid>
		<description><![CDATA[I) Présentation
wxWidgets est une librairie open source dont le but 1er est de permettre de créer des interfaces graphiques pour ses programmes (fenêtres, boutons&#8230;etc). Elle est portable mais les applications crées avec ont la particularité d&#8217;adopter le &#171;&#160;look and feel&#160;&#187; (apparence) de la plate-forme sur laquelle elles ont été compilées. Cela est dû au fait [...]]]></description>
			<content:encoded><![CDATA[<h2>I) Présentation</h2>
<p style="text-align: justify;">wxWidgets est une librairie open source dont le but 1er est de permettre de créer des interfaces graphiques pour ses programmes (fenêtres, boutons&#8230;etc). Elle est portable mais les applications crées avec ont la particularité d&#8217;adopter le &laquo;&nbsp;look and feel&nbsp;&raquo; (apparence) de la plate-forme sur laquelle elles ont été compilées. Cela est dû au fait qu&#8217;en interne, wxWidgets utilise l&#8217;API propre à chaque plate-forme (API Win32 ou juste GDI sous Windows, GTK+, Motif ou directement X11 sous Linux et autres UNIXs, Carbon ou Cocoa sous Mac&#8230;). Cependant, l&#8217;équipe de wxWidgets a également mis sur pied une version spéciale de wxWidgets, wxUniversal, qui compile sous Windows, Linux et certains périphériques embarqués, et qui s&#8217;occupe entièrement de l&#8217;affichage (le &laquo;&nbsp;look and feel&nbsp;&raquo; natif de la plate-forme n&#8217;est pas forcément respecté).</p>
<p style="text-align: justify;">Cependant, wxWidgets ne se limite pas à permettre la création d&#8217;interfaces graphiques, elle est capable de faire beaucoup d&#8217;autres choses; elle possède ses propres classes de tableau, tables de haschage, liste chaînée, elle permet de créer des applications utilisant les sockets (connections réseau), d&#8217;intégrer une zone dédiée à OpenGL dans une fenêtre pour pouvoir faire du dessin en 3D, de faire des manipulations de chaînes grâce à la classe wxString, contient une sous-librairie, wxHTML, qui permet de visualiser une page HTML, possède son propre système d&#8217;aide semblable aux CHM de Windows, peut utiliser des ressources au format XML, peut utiliser des bases de données&#8230;etc.</p>
<p style="text-align: justify;">Et tout cela est gratuit et portable, pourquoi s&#8217;en priver ? <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><span id="more-123"></span></p>
<h2>II) Installation</h2>
<p>Quelle que soit la plate-forme choisie, wxWidgets n&#8217;est pas livrée pré-compilée; c&#8217;est à vous de la compiler à partir des sources.</p>
<p>Mais avant de compiler, cherchez le fichier setup.h et modifiez-le si besoin. Ce fichier contient des #defines qui définissent comment la librairie doit être compilée. Personnellement, j&#8217;ai l&#8217;habitude de changer le :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code58'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12358"><td class="code" id="p123code58"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Recommended setting: 1 if you intend to use OpenGL, 0 otherwise</span>
<span style="color: #339900;">#define wxUSE_GLCANVAS</span></pre></td></tr></table></div>

<p>en :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code59'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12359"><td class="code" id="p123code59"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Recommended setting: 1 if you intend to use OpenGL, 0 otherwise</span>
<span style="color: #339900;">#define wxUSE_GLCANVAS</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ce qui permet d&#8217;utiliser la classe wxGLCanvas si l&#8217;on veut pouvoir créer une zone OpenGL dans une fenêtre d&#8217;un programme wxWidgets.</p>
<p style="text-align: justify;">Ensuite, si vous êtes sous Visual C++, il lancez la compilation du projet situé dans le répertoire src. Vous avez le temps d&#8217;aller boire un café en attendant, vu que le compilateur met un certain temps à &laquo;&nbsp;digérer&nbsp;&raquo; la librairie <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Après, il faut aller dans le menu Tools-&gt;Options-&gt;onglet Directories, rajouter le répertoire lib lorsque &laquo;&nbsp;Librairies files&nbsp;&raquo; est sélectionné et rajouter le répertoire include lorsque &laquo;&nbsp;Include files&nbsp;&raquo; est sélectionné.</p>
<p style="text-align: justify;">Enfin, pour créer un projet, je vous recommande de reprendre un des projets du répertoire samples qui contient de nombreux exemples et de le réutiliser.</p>
<p style="text-align: justify;">Si vous utilisez Dev-C++, vous pouvez trouver <a href="http://michel.weinachter.free.fr/indexfr.html">des DevPacks ici</a> ou compiler vous-mêmes; si vous optez pour cette solution, regardez du côté des makefiles, du fichier configure ou essayez d&#8217;importer le projet Visual C++.</p>
<p style="text-align: justify;">[UPDATE du 23/09/04 : vous pouvez également télécharger un DevPack <a href="http://cfred.free.fr/DevPack/">ICI</a> pour wxWidgets 2.5.2, merci à fredcl <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  D'ailleurs il me fait remarquer qu'il faut impérativement désinstaller toute version précédente du DevPack avant d'installer celle-ci ^^]</p>
<p>Si vous êtes sous Linux, il faut faire le triplet habituel</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code60'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12360"><td class="code" id="p123code60"><pre class="shell" style="font-family:monospace;">./configure
&nbsp;
make
make install</pre></td></tr></table></div>

<p>Mais renseignez-vous avant sur les options que vous pouvez passer au ./configure (notamment &#8211;with-opengl et &#8211;use-gtk2 il me semble, mailez-moi si je me trompe).</p>
<p>Ensuite, pour la compilation en ligne de commande on fait:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code61'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12361"><td class="code" id="p123code61"><pre class="shell" style="font-family:monospace;">g++ mon_code.cpp -o mon_executable `wx-config --libs --cflags`</pre></td></tr></table></div>

<h2>III) Premier programme</h2>
<p>Allez c&#8217;est parti, maintenant on code !</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code62'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12362"><td class="code" id="p123code62"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// App.h</span>
<span style="color: #339900;">#ifndef APP_H</span>
<span style="color: #339900;">#define APP_H</span>
&nbsp;
<span style="color: #666666;">// Le header principal de wxWidgets</span>
<span style="color: #339900;">#include </span>
&nbsp;
<span style="color: #666666;">// La classe App représente l'application</span>
<span style="color: #0000ff;">class</span> App <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> wxApp
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
&nbsp;
   <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">bool</span> OnInit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>  <span style="color: #666666;">// OnInit() est l'équivalent du main() classique :</span>
                           <span style="color: #666666;">// c'est là que débute le programme.</span>
&nbsp;
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif // APP_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p123code63'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p12363"><td class="code" id="p123code63"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// App.cpp</span>
<span style="color: #339900;">#include &quot;App.h&quot;</span>
&nbsp;
<span style="color: #666666;">// Cette macro crée l'objet global de type App qui représente l'application.</span>
IMPLEMENT_APP<span style="color: #008000;">&#40;</span>App<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #666666;">// Equivalent de main()</span>
<span style="color: #0000ff;">bool</span> App<span style="color: #008080;">::</span><span style="color: #007788;">OnInit</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// On crée une nouvelle wxFrame (une fenêtre), avec new.</span>
   <span style="color: #666666;">// Notez qu'il est inutile d'appeler delete, wxWidgets le fera</span>
   <span style="color: #666666;">// automatiquement :)</span>
   wxFrame<span style="color: #000040;">*</span> frame <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> wxFrame<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">-</span><span style="color: #0000dd;">1</span>, <span style="color: #FF0000;">&quot;Hello World !&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On centre la fenêtre</span>
   frame<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>Center<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On l'affiche</span>
   frame<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>Show<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// On précise à wxWidgets que ce sera la fenêtre principale;</span>
   <span style="color: #666666;">// grâce à cela il pourra détruire (delete) la fenêtre en fin d'application</span>
   <span style="color: #666666;">// et c'est aussi grâce à cela qu'un clic sur la croix ferme le programme</span>
   <span style="color: #666666;">// (et pas seulement la fenêtre).</span>
   this<span style="color: #000040;">-</span><span style="color: #000040;">&amp;</span>gt<span style="color: #008080;">;</span>SetTopWindow<span style="color: #008000;">&#40;</span>frame<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// Pour finir on renvoie TRUE, ce qui signifie que l'application doit continuer</span>
   <span style="color: #666666;">// (et rentrer dans la boucle d'évènements).</span>
&nbsp;
   <span style="color: #0000ff;">return</span> TRUE<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h2>IV) Conclusion</h2>
<p style="text-align: justify;">Voilà, ce tutorial n&#8217;est qu&#8217;une première approche à wxWidgets, normalement devraient suivre d&#8217;autres tuts sur les menus, les boutons, les listes&#8230;</p>
<p style="text-align: justify;">Comme d&#8217;habitude, pour toute remarque/critique/suggestion, laissez un message ci-dessous ou mailez-moi à funto66 at gmail.com.</p>
<blockquote>
<p style="text-align: justify;">Cet article provient du tutorial publié par Funto le 08/08/2005 sur l&#8217;ancien site de Coder-Studio.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/introduction-a-wxwidgets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les Bases du langage C</title>
		<link>http://www.coder-studio.com/blog/les-bases-du-langage-c/</link>
		<comments>http://www.coder-studio.com/blog/les-bases-du-langage-c/#comments</comments>
		<pubDate>Sat, 30 Jul 2005 16:29:13 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[débutant]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=15</guid>
		<description><![CDATA[Introduction
Je suppose que si vous êtes arrivé jusqu&#8217;à cette page web, soit vous vous êtes perdu soit vous voulez vraiment apprendre à programmer en langage C ^^. Si vous êtes dans ce cas, bienvenue chez les programmeurs ! Alors, qu&#8217;est-ce que le C ? Le C est un langage de programmation; on écrit un programme [...]]]></description>
			<content:encoded><![CDATA[<h2 style="text-align: justify;">Introduction</h2>
<p style="text-align: justify;">Je suppose que si vous êtes arrivé jusqu&#8217;à cette page web, soit vous vous êtes perdu soit vous voulez vraiment apprendre à programmer en langage C ^^. Si vous êtes dans ce cas, bienvenue chez les programmeurs ! Alors, qu&#8217;est-ce que le C ? Le C est un langage de programmation; on écrit un programme dans ce langage, et ensuite le texte que vous avez tapé est converti par un &laquo;&nbsp;compilateur&nbsp;&raquo; en langage binaire 0 et 1 compréhensible par le processeur de votre ordinateur (un fichier .exe). Donc, pour commencer, il vous faut un compilateur et un éditeur (le bloc-notes peut suffire comme éditeur mais il y a beaucoup mieux <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ). Un environnement qui intègre et compilateur et éditeur est appelé IDE (Integrated Development Environment). La plupart de ceux que je vais vous proposer sont des compilateurs C++. Qu&#8217;est-ce que le C++? C&#8217;est un autre langage, mais qui en réalité est compatible avec le C (un programme écrit en C peut se compiler avec un compilateur C++ mais pas l&#8217;inverse). Le C++, c&#8217;est donc tout le C, mais avec des notions supplémentaires (templates, objets, surcharge de fonctions&#8230;). Le C et le C++ sont définis par les normes ANSI/ISO (ce sont des organismes de normalisation, en gros ils donnent les règles que doit respecter un compilateur pour pouvoir être présenté comme un compilateur C ANSI ou C++ ANSI).</p>
<p style="text-align: justify;"><span id="more-15"></span>Voici donc les IDEs majeurs (sous Windows) :</p>
<p style="text-align: justify;"><strong>Visual C++ de Microsoft</strong> : il est payant, très utilisé, et est compatible avec la plupart des librairies (j&#8217;expliquerai plus tard). Il est spécialement pratique à utilisé accompagné de Visual Assist (payant). La version 6.0 est &laquo;&nbsp;indépendante&nbsp;&raquo; alors que la version 7.0 est intégrée à Visual Studio.NET (il vous faudra un PC bien puissant pour utiliser celle-ci&#8230;)</p>
<p style="text-align: justify;"><strong>Dev-C++ de Bloodshed Software</strong> : il est gratuit et sous licence GPL open source, vous pouvez le trouver sur <a href="http://www.bloodshed.net">http://www.bloodshed.net</a>. Cet IDE s&#8217;appuie sur le compilateur MinGW, qui est une version Windows du compilateur pour Linux GCC. Cet environnement est très bien aussi et est aussi compatible avec la plupart des librairies (notamment celles que nous utiliserons plus tard). Prenez la bêta 5.</p>
<p style="text-align: justify;"><strong>Borland C++Builder</strong> : il est payant (trop d&#8217;ailleurs ?) mais est fourni avec la librairie VCL, ce qui lui donne un avantage non négligeable sur les autres (en gros il permet de créer des interfaces graphiques (fenêtres, boutons&#8230; de Windows) très facilement). Cependant, Borland met à disposition de tous le compilateur de la version 5.5 de C++Builder, sans l&#8217;environnement de développement. Qu niveau des librairies, il me semble qu&#8217;il est possible d&#8217;importer celles de Visual C++.</p>
<p style="text-align: justify;">Cf <a title="http://www.borland.com/products/downloads/download_cbuilder.html" href="http://www.borland.com/products/downloads/download_cbuilder.html">http://www.borland.com/products/downloads/download_cbuilder.html</a></p>
<p style="text-align: justify;"><strong>Borland C++BuilderX </strong> : c&#8217;est le tout nouvel IDE de Borland, qui semble très prometteur. Vous pouvez l&#8217;associer à n&#8217;importe quel compilateur (MinGW, le compilateur de Borland, celui de Visual C++&#8230;)</p>
<p style="text-align: justify;"><strong>LCC-Win32</strong> : c&#8217;est un vieil IDE reposant sur le compilateur LCC; il est gratuit mais n&#8217;est plus développé et ne compile que le C (pas le C++). Pour les librairies, c&#8217;est comme pour Borland, on peut importer celles de Visual C++.</p>
<p style="text-align: justify;">Il existe encore d&#8217;autres IDEs/compilateurs C++ (Digital Mars C++, Symantec C++, Watcom C++, CodeWarrior&#8230;), mais je vous ai cité les principaux compilateurs pour Windows (Win32). Cependant, il y a aussi des compilateurs pour MS-DOS (Turbo C++, DJGPP) mais ceux-ci ne seront pas compatibles dès lors que nous voudrons utiliser des librairies pour Win32. Cependant, vous pouvez très bien les utiliser pour ce tutorial sur le langage C, vu qu&#8217;ils respectent les normes ANSI/ISO.</p>
<p style="text-align: justify;">Dans la suite de ce tutorial, je considérerai que vous utilisez Visual C++ 6.0 ou Dev-C++ 5 bêta. Pour les autres, les explications doivent être à peu près semblables.</p>
<h2 style="text-align: justify;">II) Premier programme</h2>
<p style="text-align: justify;">Bon, c&#8217;est pas tout ça, mais faudrait commencer ! <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Ouvrez votre IDE, et créez un nouveau &laquo;&nbsp;projet&nbsp;&raquo; (un projet rassemble tout ce qui concerne la création d&#8217;un programme) (Fichier -&gt;Nouveau -&gt; Projet ou File -&gt;New -&gt;Onglet Project, enfin vous connaissez <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ). Le projet sera de type Win32 Console Application sous Visual C++ 6.0 et Console Application (langage C) sous Dev-C++. Donnez-lui un nom (&laquo;&nbsp;Hello&nbsp;&raquo;) et cliquez sur OK. Sous Visual C++ 6.0, choisissez &laquo;&nbsp;An empty Project&nbsp;&raquo;.</p>
<p style="text-align: justify;">Maintenant que votre projet est créé et ouvert, vous devez y ajouter un fichier &laquo;&nbsp;hello.c&nbsp;&raquo; (sous Dev-C++ vous avez déjà un fichier main.c, faites un clic droit sur l&#8217;onglet et choisissez Fermer; n&#8217;enregistrez pas). Pour cela, sous Visual C++ 6.0 ouvrez l&#8217;onglet File View et faites File -&gt;New -&gt; Onglet Files -&gt;C++ Source File. Appelez-le hello.c. Si vous regardez dans l&#8217;arborescence de l&#8217;onglet File View vous verrez que le fichier hello.c est bien ajouté dans les Source Files. Les dossiers que vous voyez n&#8217;existent pas réellement, ils permettent de séparer les fichiers pour pouvoir mieux les repérer. Pour les utilisateurs de Dev-C++ : faites Fichier -&gt; Nouveau -&gt; Fichier Source -&gt; Ajouter au projet? Yes -&gt; enregistrez-le sous hello.c.</p>
<p>Bon, si vous avez suivi jusque là, on peut enfin commencer à coder ! Recopiez dans hello.c ceci (en respectant majuscules/minuscules !) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p15code66'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1566"><td class="code" id="p15code66"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// hello.c</span>
<span style="color: #339933;">#include &quot;stdio.h&quot;;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hello World !&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   getchar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Bon, ne vous effrayez pas, vous comprendrez tout ça ?. Maintenant, sous Dev-C++ faites Exécuter -&gt;Compiler et exécuter. Sous Visual C++, vous devez voir dans une barre d&#8217;outils &laquo;&nbsp;Win32 Debug&nbsp;&raquo; : changez ça en &laquo;&nbsp;Win32 Release&nbsp;&raquo;; ça permettra au compilateur de ne pas inclure d&#8217;informations de débogage dans l&#8217;exécutable final : votre .exe sera moins gros. Faites Build -&gt; Build Hello.exe, puis cliquez sur le point d&#8217;exclamation rouge pour commencer l&#8217;exécution de votre programme.</p>
<p style="text-align: justify;">Que fait votre programme? Il affiche dans une console MS-DOS (bien que le programme soit un programme Win32, je le rappelle) &laquo;&nbsp;Hello World !&nbsp;&raquo; puis attend que vous appuyez sur Entrée pour quitter. Aux utilisateurs de Visual C++ : Vous verrez écrit &laquo;&nbsp;Press any key to continue&nbsp;&raquo;, ceci est dû à l&#8217;environnement, si vous exécutez votre .exe depuis l&#8217;explorateur Windows ce message ne s&#8217;affiche pas.</p>
<p style="text-align: justify;">Bon, maintenant on passe à l&#8217;explication. Avant tout, il faut savoir que l&#8217;exécution du programme est séquentielle : les lignes que vous tapez sont des instructions, et celles-ci sont exécutées les unes après les autres, dans l&#8217;ordre dans lequel vous les avez écrit.</p>
<p style="text-align: justify;">Commençons par la 1ère ligne : &laquo;&nbsp;//Hello.c&nbsp;&raquo;. Vous pouvez très bien l&#8217;enlever, le programme se compilera de la même façon : c&#8217;est un commentaire. Vous pouvez marquer ce que vous voulez à la place de &laquo;&nbsp;Hello.c&nbsp;&raquo;, je marque cela juste pour connaître le nom du fichier. En C et en C++, tout ce qui suit &laquo;&nbsp;//&nbsp;&raquo; jusqu&#8217;à la fin de la ligne est un commentaire, de même que tout ce qui est placé entre &laquo;&nbsp;/*&nbsp;&raquo; et &laquo;&nbsp;*/&nbsp;&raquo; (sans les guillemets).</p>
<p style="text-align: justify;">Voyons la 2ème ligne: &laquo;&nbsp;#include&lt;stdio.h&gt;&nbsp;&raquo;. Cette ligne n&#8217;est pas vraiment une instruction : c&#8217;est une directive du préprocesseur comme toutes celles débutant par un #. Ne vous effrayez pas ! Bon, pour simplifier, on dira que c&#8217;est elle qui vous permet d&#8217;écrire printf et getchar par la suite sans provoquer d&#8217;erreur à la compilation. Je rentrerai dans les détails plus tard, pour l&#8217;instant sachez qu&#8217;il faut la placer en début de fichier.</p>
<p style="text-align: justify;">Maintenant, la 3ème ligne : &laquo;&nbsp;int main()&nbsp;&raquo;. Celle-ci dénote le début du bloc principal : c&#8217;est là que commencera l&#8217;exécution de votre programme, tout ce qui suit main() est exécuté en 1er. Un bloc d&#8217;instructions est délimité par { et }. Notre programme ne comporte qu&#8217;un seul bloc d&#8217;instructions.</p>
<p style="text-align: justify;">&laquo;&nbsp;printf(&laquo;&nbsp;Hello World !&nbsp;&raquo;);&nbsp;&raquo; : ceci est notre 1ère instruction. printf commande l&#8217;écriture à l&#8217;écran de texte. On dit que printf est une fonction, et que la ligne &laquo;&nbsp;printf(&laquo;&nbsp;Hello World !&nbsp;&raquo;);&nbsp;&raquo; est un appel à la fonction printf. Un appel de fonction est toujours composé du nom de la fonction (printf), d&#8217;une parenthèse ouvrante, d &#8216; &laquo;&nbsp;argument(s)&nbsp;&raquo; (le &laquo;&nbsp;Hello World !&nbsp;&raquo;) et d&#8217;une parenthèse fermante. Et le point-virgule? Il délimite la fin d&#8217;une instruction. L&#8217;oubli d&#8217;un point-virgule est une erreur très fréquente en programmation en C, et elle est dure à repérer pour les débutants : faites attention !</p>
<p style="text-align: justify;">&nbsp;&raquo; getchar();&nbsp;&raquo; : ceci est un autre appel à une fonction, la fonction &laquo;&nbsp;getchar&nbsp;&raquo;. Vous remarquerez qu&#8217;on ne lui passe pas d&#8217;arguments, car elle n&#8217;en a pas besoin; c&#8217;est elle qui attend l&#8217;appui sur la touche Entrée. En effet, recompilez votre programme sans cette ligne (mettez-la en commentaire) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p15code67'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p1567"><td class="code" id="p15code67"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// hello.c</span>
<span style="color: #339933;">#include &quot;stdio.h&quot;;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span>
<span style="color: #009900;">&#123;</span>
   <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Hello World !&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">//  getchar();    // La ligne est mise en commentaire, elle n'est pas compilée.</span>
   <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">A l&#8217;exécution du programme (hors IDE, je veux dire pour les utilisateurs de VC++, ouvrez votre exécutable depuis l&#8217;explorateur Windows), le programme quitte avant que vous ayez pu lire quoi que ce soit ! Voilà pourquoi il vous faut rajouter l&#8217;appel à la fonction getchar().</p>
<p style="text-align: justify;">Enfin, le &laquo;&nbsp;return 0;&nbsp;&raquo;, placé dans le bloc main(), indique la sortie du programme (il quitte). Si vous le placez avant getchar() par exemple, getchar() ne sera pas exécuté car le programme aura quitté avant. Le } délimite la fin du bloc main (principal).</p>
<p style="text-align: justify;">Ouf ! Voilà, vous avez terminé le 1er tutorial sur la programmation en C, maintenant essayez de changer l&#8217;ordre des lignes, de rajouter des appels à printf avec un texte différent (à oui, au fait, j&#8217;ai oublié pour les guillemets dans printf : ils montrent que l&#8217;argument passé à printf est une chaîne de caractères, un texte quoi, vous verrez ça plus en détail + tard, encore une fois <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</p>
<p style="text-align: justify;">Pour toute remarque, conseil, correction : funto66 at gmail.com <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<blockquote>
<p style="text-align: justify;">Cet article provient du tutorial publié par Funto le 30/07/2005 sur l&#8217;ancien site de Coder-Studio.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/les-bases-du-langage-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La factory</title>
		<link>http://www.coder-studio.com/blog/la-factory/</link>
		<comments>http://www.coder-studio.com/blog/la-factory/#comments</comments>
		<pubDate>Tue, 21 Dec 2004 17:41:22 +0000</pubDate>
		<dc:creator>twxs</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[factory]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=164</guid>
		<description><![CDATA[La Factory, brrr
Dans ce tutorial, je vais tenter d&#8217;aborder le design pattern factory (fabrique pour les anglophobes).
A mon habitude, nous allons retrouver la même ligne directrice que pour les précédents tutoriaux.
Je vais commencer par expliquer brièvement le principe de la factory, ensuite en découlera une première implémentation en C++ et enfin on essayera de rendre [...]]]></description>
			<content:encoded><![CDATA[<p><strong>La Factory, brrr</strong></p>
<p style="text-align: justify;">Dans ce tutorial, je vais tenter d&#8217;aborder le design pattern factory (fabrique pour les anglophobes).<br />
A mon habitude, nous allons retrouver la même ligne directrice que pour les précédents tutoriaux.<br />
Je vais commencer par expliquer brièvement le principe de la factory, ensuite en découlera une première implémentation en C++ et enfin on essayera de rendre ça le plus générique possible.</p>
<p style="text-align: justify;"><span id="more-164"></span></p>
<h2>Definition</h2>
<p style="text-align: justify;">La factory est en fait un objet dont le rôle est de créer des instances d&#8217;autres objets.<br />
Dans un modeleur par exemple, on pourrait avoir une factory d&#8217;objets géométriques qui servirait à créer des sphères, cônes, etc&#8230;</p>
<h2>Première Implémentation :</h2>
<p style="text-align: justify;">Nous allons prendre le cas d&#8217;une factory d&#8217;objets géométriques dont le but est de fournir des objets héritant de l&#8217;interface Shape.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code81'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16481"><td class="code" id="p164code81"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">De plus, nous avons dans l&#8217;application des objets implémentant l&#8217;interface shape comme Sphere, Cone, &#8230;.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code82'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16482"><td class="code" id="p164code82"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Sphere <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> Cone   <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>...<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Une premiere implémentation de la factory pourrait donner ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code83'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16483"><td class="code" id="p164code83"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> ShapeFactory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  Shape <span style="color: #000040;">*</span> createSphere<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  Shape <span style="color: #000040;">*</span> createCone<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Cone<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ce qui donne à l&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code84'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16484"><td class="code" id="p164code84"><pre class="cpp" style="font-family:monospace;">ShapeFactory factory<span style="color: #008080;">;</span>
&nbsp;
Shape <span style="color: #000040;">*</span> sphere <span style="color: #000080;">=</span> factory.<span style="color: #007788;">createSphere</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sphere<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>display<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Cette première approche fonctionne, mais a le désavantage de rendre le code de la factory dépendant de l&#8217;application.<br />
Nous allons tenter de définir la factory de manière générique (template <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) afin de pouvoir la réutiliser dans d&#8217;autres cas.</p>
<h2>On templatise un peu ?</h2>
<p style="text-align: justify;">On peut voir la factory comme une map : à une clef donnée, on associe un type d&#8217;objet a créer.</p>
<p style="text-align: justify;">On devrait donc avoir au niveau des paramètres de la factory générique, le type de la clef et le type d&#8217;objet que la factory retourne. Ceci nous donne le prototype suivant :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code85'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16485"><td class="code" id="p164code85"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Et à  l&#8217;utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code86'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16486"><td class="code" id="p164code86"><pre class="cpp" style="font-family:monospace;">Factory shapeFactory<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">De plus, on s&#8217;attend à pouvoir écrire quelque chose du genre :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code87'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16487"><td class="code" id="p164code87"><pre class="cpp" style="font-family:monospace;">Shape <span style="color: #000040;">*</span>sphere <span style="color: #000080;">=</span> shapeFactory.<span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">On enrichit donc notre esquisse de la classe  :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code88'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16488"><td class="code" id="p164code88"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  Object <span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Pour le corps de la méthode create, nous avons besoin de réellement créer une instance d&#8217;un objet que la factory ne connait pas. Comme ceci ne peut pas se faire par magie, il va falloir enregistrer dans la factory une fonction capable de créer chaque objet et les associer à une clef.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code89'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16489"><td class="code" id="p164code89"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
<span style="color: #666666;">// un pointeur de fonction qui retourne un Object*</span>
  <span style="color: #0000ff;">typedef</span> Object <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>Creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
  map _registeredCreator<span style="color: #008080;">;</span>
&nbsp;
  <span style="color: #0000ff;">bool</span> <span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span>Key key, Creator creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>_registeredCreator.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> _registeredCreator.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span> <span style="color: #666666;">// la clef est deja utilisé</span>
    _registeredCreator.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span>pair<span style="color: #008000;">&#40;</span>key, creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
&nbsp;
  Object <span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span>Key key<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    Object <span style="color: #000040;">*</span>object<span style="color: #008080;">;</span>
    Creator creator<span style="color: #008080;">;</span>
    map<span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// on cherche le pointeur de fonction associé a la clef</span>
    it <span style="color: #000080;">=</span> _registeredCreator.<span style="color: #007788;">find</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>it <span style="color: #000080;">==</span> _registeredCreator.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span> <span style="color: #666666;">// on ne l'a pas trouvé</span>
&nbsp;
    <span style="color: #666666;">// on récupère le pointeur de fonction</span>
    creator <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>it<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">second</span><span style="color: #008080;">;</span>
    <span style="color: #666666;">// on appelle la fonction pour créer un nouvel objet</span>
    object <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>creator<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #666666;">// on retourne l'objet</span>
    <span style="color: #0000ff;">return</span> object<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Regardons maintenant comment utiliser tout ça :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code90'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16490"><td class="code" id="p164code90"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// des fonctions de création d'objets</span>
Shape <span style="color: #000040;">*</span>createSphere<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
Shape <span style="color: #000040;">*</span>createCone<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Cone<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
&nbsp;
Factory shapeFactory<span style="color: #008080;">;</span>
shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span>, createSphere<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Cone&quot;</span>, createCone<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
Shape <span style="color: #000040;">*</span>sphere <span style="color: #000080;">=</span> shapeFactory.<span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Ici le problème reste la nécessité d&#8217;avoir des fonctions &laquo;&nbsp;C&nbsp;&raquo; à mettre dans le code, et de devoir enregistrer ces fonctions à la main. Donc à chaque ajout d&#8217;objet géométrique devoir aller remodifier ce code d&#8217;initialisation de la factory.</p>
<p style="text-align: justify;">Pour rendre ceci un peu plus propre, nous allons définir ces fonctions en statique dans chaque objet géométrique et se servir de l&#8217;initialisation des CRT pour enregistrer les fonctions automatiquement.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code91'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16491"><td class="code" id="p164code91"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// sphere.h</span>
<span style="color: #0000ff;">class</span> Sphere <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">static</span> Shape<span style="color: #000040;">*</span> create<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> <span style="color: #0000ff;">register</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code92'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16492"><td class="code" id="p164code92"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// sphere.pp</span>
<span style="color: #339900;">#include &quot;ShapeFactory.h&quot; // on considère que la shapeFactory est une variable globale accessible par ce fichier</span>
&nbsp;
Shape <span style="color: #000040;">*</span> Shpere<span style="color: #008080;">::</span><span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">new</span> Sphere<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #666666;">// auto enregistrement :</span>
<span style="color: #0000ff;">bool</span> Sphere<span style="color: #008080;">::</span><span style="color: #0000ff;">register</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span>, Sphere<span style="color: #008080;">::</span><span style="color: #007788;">create</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Il est possible d&#8217;utiliser des macros pour encore réduire la taille du code à produire.</p>
<p style="text-align: justify;">Petite explication : au lancement du programme, la variable statique register est initialisée. Cette initialisation passe par l&#8217;appel de la methode shapeFactory::register qui enregistre le &laquo;&nbsp;create&nbsp;&raquo;.</p>
<h2>Conlusion:</h2>
<p style="text-align: justify;">J&#8217;ai ici présenté l&#8217;implémentation &laquo;&nbsp;générique&nbsp;&raquo; d&#8217;une factory; pour pousser un peu plus l&#8217;exemple du modeleur, on peut imaginer que l&#8217;interface Shape permette de décrire des attributs (association nom / valeur). Une sphère par exemple aura un paramètre de type float nommé &laquo;&nbsp;radius&nbsp;&raquo;.<br />
Notre petite application graphique aura à parcourir les entrées de la factory pour y découvrir tous les objets &laquo;&nbsp;instanciables&nbsp;&raquo; et fournir à l&#8217;utilisateur un panel de boutons pour créer des Shapes.<br />
A partir de là, à chaque Shape créé, elle pourra construire une boîte de dialogue d&#8217;édition adaptée à l&#8217;objet (à la mode 3DS), SANS en connaitre le type réel.</p>
<h2>Pour aller plus loin :</h2>
<p style="text-align: justify;">Il est possible de s&#8217;abstraire de l&#8217;écriture de la fonction create statique dans les classes en utilisant les templates pour créer des objets dont le rôle est de remplacer la fonction statique.</p>
<p style="text-align: justify;">A l&#8217;utilisation cela donne quelque chose comme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p164code93'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16493"><td class="code" id="p164code93"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Shape<span style="color: #008080;">::</span><span style="color: #0000ff;">register</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span> <span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Shape&quot;</span>, Creator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Il faut pour cela modifier un peu la classe factory, mais je vous le laisse en exercice <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  (j&#8217;ai toujours révé de dire ça un jour&#8230;)</p>
<p style="text-align: justify;">Dernier point, on peut utiliser les singleton pour ne pas avoir à stocker la factory dans une variable globale.</p>
<p><span style="color: #ff0000;"><strong>joyeuses fetes <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </strong></span></p>
<p><strong>Twxs</strong></p>
<blockquote><p>Cet article provient du tutorial publié par Twxs le 24/12/2004 sur l&#8217;ancien site de Coder-Studio.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/la-factory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
