Red-Black Trees are now used for duplicate detection, and planned

to be used for unordered map storage. This is because AAs still
don't work correctly and even if they did, require the user to
define both toHash and opCmp/opEquals for every YAML
struct/class. Now only opCmp needs to be defined.
Documentation/tutorials/examples have been updated accordingly.
This commit is contained in:
Ferdinand Majerech 2012-01-23 15:57:26 +01:00
parent 07eadc9403
commit 9596806644
34 changed files with 623 additions and 250 deletions

View file

@ -48,7 +48,7 @@
<div class="section" id="custom-yaml-data-types">
<h1>Custom YAML data types<a class="headerlink" href="#custom-yaml-data-types" title="Permalink to this headline"></a></h1>
<p>Sometimes you need to serialize complex data types such as classes. To do this
you could use plain nodes such as mappings with class data members. YAML also
you could use plain nodes such as mappings with classes&#8217; fields. YAML also
supports custom types with identifiers called <em>tags</em>. That is the topic of this
tutorial.</p>
<p>Each YAML node has a tag specifying its type. For instance: strings use the tag
@ -62,11 +62,13 @@ each node to hold data type corresponding to its tag. <em>Constructor</em> store
functions to process each supported tag. These are supplied by the user using
the <em>addConstructorXXX()</em> methods, where <em>XXX</em> is <em>Scalar</em>, <em>Sequence</em> or
<em>Mapping</em>. <em>Constructor</em> is then passed to <em>Loader</em>, which parses YAML input.</p>
<p>Struct types have no specific requirements for YAML support. Class types should
define the <em>opEquals()</em> operator - this is used in equality comparisons of
nodes. Default class <em>opEquals()</em> compares references, which means two identical
objects might be considered unequal. (Default struct <em>opEquals()</em> compares
byte-by-byte, sometimes you might want to override that as well.)</p>
<p>Structs and classes must implement the <em>opCmp()</em> operator for YAML support. This
is used for duplicate detection in mappings, sorting and equality comparisons of
nodes. The signature of the operator that must be implemented is
<tt class="docutils literal"><span class="pre">const</span> <span class="pre">int</span> <span class="pre">opCmp(ref</span> <span class="pre">const</span> <span class="pre">MyStruct</span> <span class="pre">s)</span></tt> for structs where <em>MyStruct</em> is the
struct type, and <tt class="docutils literal"><span class="pre">int</span> <span class="pre">opCmp(Object</span> <span class="pre">o)</span></tt> for classes. Note that the class
<em>opCmp()</em> should not alter the compared values - it is not const for compatibility
reasons.</p>
<p>We will implement support for an RGB color type. It is implemented as the
following struct:</p>
<div class="highlight-d"><div class="highlight"><pre><span class="k">struct</span> <span class="n">Color</span>
@ -74,6 +76,14 @@ following struct:</p>
<span class="kt">ubyte</span> <span class="n">red</span><span class="p">;</span>
<span class="kt">ubyte</span> <span class="n">green</span><span class="p">;</span>
<span class="kt">ubyte</span> <span class="n">blue</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">opCmp</span><span class="p">(</span><span class="k">ref</span> <span class="k">const</span> <span class="n">Color</span> <span class="n">c</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">red</span> <span class="p">!=</span> <span class="n">c</span><span class="p">.</span><span class="n">red</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="n">red</span> <span class="p">-</span> <span class="n">c</span><span class="p">.</span><span class="n">red</span><span class="p">;}</span>
<span class="k">if</span><span class="p">(</span><span class="n">green</span> <span class="p">!=</span> <span class="n">c</span><span class="p">.</span><span class="n">green</span><span class="p">){</span><span class="k">return</span> <span class="n">green</span> <span class="p">-</span> <span class="n">c</span><span class="p">.</span><span class="n">green</span><span class="p">;}</span>
<span class="k">if</span><span class="p">(</span><span class="n">blue</span> <span class="p">!=</span> <span class="n">c</span><span class="p">.</span><span class="n">blue</span><span class="p">)</span> <span class="p">{</span><span class="k">return</span> <span class="n">blue</span> <span class="p">-</span> <span class="n">c</span><span class="p">.</span><span class="n">blue</span><span class="p">;}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
@ -364,7 +374,7 @@ directory of the D:YAML package.</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Nov 18, 2011.
Last updated on Jan 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -78,7 +78,7 @@ script for compilation. To compile D:YAML, you first need to build CDC.
Do this by typing the following command into the console:</p>
<div class="highlight-python"><pre>dmd cdc.d</pre>
</div>
<p>Now you can use CDC to compile D:YAML.
<p>Now compile D:YAML with CDC.
To do this on Unix/Linux, use the following command:</p>
<div class="highlight-python"><pre>./cdc</pre>
</div>
@ -125,8 +125,8 @@ into the file:</p>
</div>
<div class="section" id="explanation-of-the-code">
<h3>Explanation of the code<a class="headerlink" href="#explanation-of-the-code" title="Permalink to this headline"></a></h3>
<p>First, we import the <em>yaml</em> module. This is the only module you need to import
to use D:YAML - it automatically imports all needed modules.</p>
<p>First, we import the <em>yaml</em> module. This is the only D:YAML module you need to
import - it automatically imports all needed modules.</p>
<p>Next we load the file using the <em>Loader.load()</em> method. <em>Loader</em> is a struct
used for parsing YAML documents. The <em>load()</em> method loads the file as
<strong>one</strong> YAML document, or throws <em>YAMLException</em>, D:YAML exception type, if the
@ -160,17 +160,17 @@ formatted differently. Comments are not preserved, either.</p>
</div>
<div class="section" id="compiling">
<h3>Compiling<a class="headerlink" href="#compiling" title="Permalink to this headline"></a></h3>
<p>To compile your project, you must give DMD the directories containing import
modules and the library. You also need to tell it to link with D:YAML. The import
directory should be the D:YAML package directory. You can specify it using the
<tt class="docutils literal"><span class="pre">-I</span></tt> option of DMD. The library directory should be where you put the compiled
D:YAML library. On Unix/Linux you can specify it using the <tt class="docutils literal"><span class="pre">-L-L</span></tt> option, and
link with D:YAML using the <tt class="docutils literal"><span class="pre">-L-l</span></tt> option. On Windows, the import directory is
used as the library directory. To link with the library on Windows, just add the
path to it relative to the current directory.</p>
<p>To compile your project, DMD needs to know which directories contain the
imported modules and the library. You also need to tell it to link with D:YAML.
The import directory should be the D:YAML package directory. You can specify it
using the <tt class="docutils literal"><span class="pre">-I</span></tt> option of DMD. The library directory should point to the
compiled library. On Unix/Linux you can specify it using the <tt class="docutils literal"><span class="pre">-L-L</span></tt> option,
and link with D:YAML using the <tt class="docutils literal"><span class="pre">-L-l</span></tt> option. On Windows, the import directory
is used as the library directory. To link with the library on Windows, just add
the path to it relative to the current directory.</p>
<p>For example, if you extracted and compiled D:YAML in <tt class="docutils literal"><span class="pre">/home/xxx/dyaml</span></tt>, your
project is in <tt class="docutils literal"><span class="pre">/home/xxx/dyaml-project</span></tt>, and you are currently in that
directory, you can compile the project with the following command on Unix/Linux:</p>
directory, compile the project with the following command on Unix/Linux:</p>
<div class="highlight-python"><pre>dmd -I../dyaml -L-L../dyaml -L-ldyaml main.d</pre>
</div>
<p>And the following on Windows:</p>
@ -237,7 +237,7 @@ example in the <tt class="docutils literal"><span class="pre">example/getting_st
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Nov 18, 2011.
Last updated on Jan 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -330,7 +330,7 @@ Some of these might change in the future (especially !!map and !!set).</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Nov 18, 2011.
Last updated on Jan 23, 2012.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>