<html><head>
  <meta charset="utf-8">
  <meta name="author" content="P0393r3">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css">
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    line-height: 1.4em;
}
ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #8B0040	;
    line-height: 1.4em;
    background-color: #eeeeff;
}
span.section_name {
    float: right;
    font-weight: bold;
}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }
</style>

<title>Variant: relational operators.</title>
</head>

<body>
<h3>Making Variant Greater Equal</h3>
<table class="header">
    <tbody><tr><td>Document Number:</td> <td>P0393r3, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>LWG</td></tr>
    <tr><td>Date:</td><td>2016-06-21</td></tr>
    <tr><td>Author:</td><td>Tony Van Eerd (variant at forecode.com)</td></tr>
</tbody></table>

<h3>Motivation</h3>
<p>These edits align <code>variant</code> with <code>optional</code> in making the relational operators delegate to the relational operators of the underlying types
</p>

<h3>drive by fixes:</h3>
<p>Other fixes, noticed when editing and/or suggested by LWG during review</p>
<ul>
<li><code>operator<()</code> was defined as if <code>index()</code> was signed.  It is not.</li>
<li>convert <i>Effects</i> to <i>Returns</i> if...otherwise...otherwise... (as it was getting complicated)</li>
</ul>





<h4 id="relational-operators">?.6 Relational operators <span class="section_name">[variant.relops]</span></h4>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator==(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>get&lt;i&gt;(v) == get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code>.
</dd>
<dt><del class="edit">Effects:</del></dt>
<dd><del class="edit">Equivalent to <code>return (v.valueless_by_exception() &amp;&amp; w.valueless_by_exception()) || (v.index() == w.index() &amp;&amp; get&lt;i&gt;(v) == get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.</del>
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>v.index() != w.index()</code>, <code>false</code>; otherwise if <code>v.valueless_by_exception()</code>, <code>true</code>; otherwise <code>get&lt;i&gt;(v) == get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator!=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt><ins class="edit">Requires:</ins></dt>
<dd><ins class="edit"><code>get&lt;i&gt;(v) != get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code></ins>.
<dt><del class="edit">Effects:</del></dt>
<dd><del class="edit">Equivalent to <code>return !(v == w)</code>.</del>
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>v.index() != w.index()</code>, <code>true</code>; otherwise if <code>v.valueless_by_exception()</code>, <code>false</code>; otherwise <code>get&lt;i&gt;(v) != get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&lt;(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt>Requires:</dt>
<dd><code>get&lt;i&gt;(v) &lt; get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code><ins class="edit"></ins>.
</dd>
<dt><del class="edit">Effects:</del></dt>
  <dd><del class="edit">Equivalent to <code>return (v.index() &lt; w.index()) || (v.index() == w.index() &amp;&amp; !v.valueless_by_exception() &amp;&amp; get&lt;i&gt;(v) &lt; get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code></del>.
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>w.valueless_by_exception()</code>, <code>false</code>; otherwise if <code>v.valueless_by_exception()</code>, <code>true</code>; otherwise, if <code>v.index() &lt w.index()</code>, <code>true</code>; otherwise if <code>v.index() &gt; w.index()</code>, <code>false</code>; otherwise <code>get&lt;i&gt;(v) &lt; get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>




<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&gt;(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt><ins class="edit">Requires:</ins></dt>
<dd><ins class="edit"><code>get&lt;i&gt;(v) &gt; get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code></ins>.
</dd>
<dt><del class="edit">Effects:</del></dt>
<dd><del class="edit">Equivalent to <code>return </code><del class="edit"><code>w &lt; v</code></del>.
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>v.valueless_by_exception()</code>, <code>false</code>; otherwise if <code>w.valueless_by_exception()</code>, <code>true</code>; otherwise, if <code>v.index() &gt w.index()</code>, <code>true</code>; otherwise if <code>v.index() &lt; w.index()</code>, <code>false</code>; otherwise <code>get&lt;i&gt;(v) &gt; get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&lt;=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt><ins class="edit">Requires:</ins></dt>
<dd><ins class="edit"><code>get&lt;i&gt;(v) &lt;= get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code></ins>.
</dd>
<dt><del class="edit">Effects:</del></dt>
<dd><del class="edit">Equivalent to <code>return </code><del class="edit"><code>!(v &gt; w)</code></del>.
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>v.valueless_by_exception()</code>, <code>true</code>; otherwise if <code>w.valueless_by_exception()</code>, <code>false</code>; otherwise, if <code>v.index() &lt w.index()</code>, <code>true</code>; otherwise if <code>v.index() &gt; w.index()</code>, <code>false</code>; otherwise <code>get&lt;i&gt;(v) &lt;= get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>

<p class="function">
<code>
template &lt;class... Types&gt; constexpr bool operator&gt;=(const variant&lt;Types...&gt;&amp; v, const variant&lt;Types...&gt;&amp; w);
</code>
</p>
<dl class="attribute">
<dt><ins class="edit">Requires:</ins></dt>
<dd><ins class="edit"><code>get&lt;i&gt;(v) &gt;= get&lt;i&gt;(w)</code> is a valid expression returning a type that is convertible to <code>bool</code>, for all <code>i</code></ins>.
</dd>
<dt><del class="edit">Effects:</del></dt>
<dd><del class="edit">Equivalent to <code>return !(v &lt; w)</code>.</del>
</dd>
<dt><ins class="edit">Returns:</ins></dt>
  <dd><ins class="edit">If <code>w.valueless_by_exception()</code>, <code>true</code>; otherwise if <code>v.valueless_by_exception()</code>, <code>false</code>; otherwise, if <code>v.index() &gt w.index()</code>, <code>true</code>; otherwise if <code>v.index() &lt; w.index()</code>, <code>false</code>; otherwise <code>get&lt;i&gt;(v) &gt;= get&lt;i&gt;(w)</code> with <code>i</code> being <code>v.index()</code>.
</dd>
</dl>





</body></html>




