+<p>This approach has the advantage that users of your custom data type will
+automatically use your custom parser whenever they define an option with a value
+type of your data type. The disadvantage of this approach is that it doesn't
+work if your fundamental data type is something that is already supported.</p>
+
+</li>
+
+<li>
+
+<p>Write an independent class, using it explicitly from options that need
+it.</p>
+
+<p>This approach works well in situations where you would line to parse an
+option using special syntax for a not-very-special data-type. The drawback of
+this approach is that users of your parser have to be aware that they are using
+your parser instead of the builtin ones.</p>
+
+</li>
+
+</ol>
+
+<p>To guide the discussion, we will discuss a custom parser that accepts file
+sizes, specified with an optional unit after the numeric size. For example, we
+would like to parse "102kb", "41M", "1G" into the appropriate integer value. In
+this case, the underlying data type we want to parse into is
+'<tt>unsigned</tt>'. We choose approach #2 above because we don't want to make
+this the default for all <tt>unsigned</tt> options.</p>
+
+<p>To start out, we declare our new <tt>FileSizeParser</tt> class:</p>
+
+<div class="doc_code"><pre>
+<b>struct</b> FileSizeParser : <b>public</b> cl::basic_parser<<b>unsigned</b>> {
+ <i>// parse - Return true on error.</i>
+ <b>bool</b> parse(cl::Option &O, <b>const char</b> *ArgName, <b>const</b> std::string &ArgValue,
+ <b>unsigned</b> &Val);
+};
+</pre></div>
+
+<p>Our new class inherits from the <tt>cl::basic_parser</tt> template class to
+fill in the default, boiler plate code for us. We give it the data type that
+we parse into, the last argument to the <tt>parse</tt> method, so that clients of
+our custom parser know what object type to pass in to the parse method. (Here we
+declare that we parse into '<tt>unsigned</tt>' variables.)</p>
+
+<p>For most purposes, the only method that must be implemented in a custom
+parser is the <tt>parse</tt> method. The <tt>parse</tt> method is called
+whenever the option is invoked, passing in the option itself, the option name,
+the string to parse, and a reference to a return value. If the string to parse
+is not well-formed, the parser should output an error message and return true.
+Otherwise it should return false and set '<tt>Val</tt>' to the parsed value. In
+our example, we implement <tt>parse</tt> as:</p>
+
+<div class="doc_code"><pre>
+<b>bool</b> FileSizeParser::parse(cl::Option &O, <b>const char</b> *ArgName,
+ <b>const</b> std::string &Arg, <b>unsigned</b> &Val) {
+ <b>const char</b> *ArgStart = Arg.c_str();
+ <b>char</b> *End;
+
+ <i>// Parse integer part, leaving 'End' pointing to the first non-integer char</i>
+ Val = (unsigned)strtol(ArgStart, &End, 0);
+
+ <b>while</b> (1) {
+ <b>switch</b> (*End++) {
+ <b>case</b> 0: <b>return</b> false; <i>// No error</i>
+ <b>case</b> 'i': <i>// Ignore the 'i' in KiB if people use that</i>
+ <b>case</b> 'b': <b>case</b> 'B': <i>// Ignore B suffix</i>
+ <b>break</b>;
+
+ <b>case</b> 'g': <b>case</b> 'G': Val *= 1024*1024*1024; <b>break</b>;
+ <b>case</b> 'm': <b>case</b> 'M': Val *= 1024*1024; <b>break</b>;
+ <b>case</b> 'k': <b>case</b> 'K': Val *= 1024; <b>break</b>;
+
+ default:
+ <i>// Print an error message if unrecognized character!</i>
+ <b>return</b> O.error("'" + Arg + "' value invalid for file size argument!");
+ }
+ }
+}
+</pre></div>
+
+<p>This function implements a very simple parser for the kinds of strings we are
+interested in. Although it has some holes (it allows "<tt>123KKK</tt>" for
+example), it is good enough for this example. Note that we use the option
+itself to print out the error message (the <tt>error</tt> method always returns
+true) in order to get a nice error message (shown below). Now that we have our
+parser class, we can use it like this:</p>
+
+<div class="doc_code"><pre>
+<b>static</b> <a href="#cl::opt">cl::opt</a><<b>unsigned</b>, <b>false</b>, FileSizeParser>
+MFS(<i>"max-file-size"</i>, <a href="#cl::desc">cl::desc</a>(<i>"Maximum file size to accept"</i>),
+ <a href="#cl::value_desc">cl::value_desc</a>("<i>size</i>"));
+</pre></div>
+
+<p>Which adds this to the output of our program:</p>
+
+<div class="doc_code"><pre>
+OPTIONS:
+ -help - display available options (-help-hidden for more)
+ ...
+ <b>-max-file-size=<size> - Maximum file size to accept</b>
+</pre></div>
+
+<p>And we can test that our parse works correctly now (the test program just
+prints out the max-file-size argument value):</p>
+
+<div class="doc_code"><pre>
+$ ./test
+MFS: 0
+$ ./test -max-file-size=123MB
+MFS: 128974848
+$ ./test -max-file-size=3G
+MFS: 3221225472
+$ ./test -max-file-size=dog
+-max-file-size option: 'dog' value invalid for file size argument!
+</pre></div>
+
+<p>It looks like it works. The error message that we get is nice and helpful,
+and we seem to accept reasonable file sizes. This wraps up the "custom parser"
+tutorial.</p>
+
+</div>