<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1281: CopyConstruction and Assignment between ratios having the same normalized form</title>
<meta property="og:title" content="Issue 1281: CopyConstruction and Assignment between ratios having the same normalized form">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1281.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Resolved">Resolved</a> status.</em></p>
<h3 id="1281"><a href="lwg-defects.html#1281">1281</a>. CopyConstruction and Assignment between ratios having the same normalized form</h3>
<p><b>Section:</b> 21.5.3 <a href="https://wg21.link/ratio.ratio">[ratio.ratio]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Vicente Juan Botet Escrib&aacute; <b>Opened:</b> 2009-12-07 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#ratio.ratio">issues</a> in [ratio.ratio].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>
<p>
CopyConstruction and Assignment between <code>ratio</code>s having the same
normalized form. Current
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf">N3000</a>
do not allows to copy-construct or assign <code>ratio</code> instances of
<code>ratio</code> classes having the same normalized form.
</p>

<p>
Two <code>ratio</code> classes <code>ratio&lt;N1,D1&gt;</code> and
<code>ratio&lt;N2,D2&gt;</code> have the same normalized form if
</p>

<blockquote><pre>
ratio&lt;N1, D1&gt;::num == ratio&lt;N2, D2&gt;::num &amp;&amp;
ratio&lt;N1, D1&gt;::den == ratio&lt;N2, D2&gt;::den
</pre></blockquote>

<p>
This simple example
</p>

<blockquote><pre>
ratio&lt;1,3&gt; r1;
ratio&lt;3,9&gt; r2;
r1 = r2; // (1)
</pre></blockquote>

<p>
fails to compile in (1). Other example
</p>

<blockquote><pre>
ratio&lt;1,3&gt; r1;
ratio_subtract&lt;ratio&lt;2,3&gt;, ratio&lt;1,3&gt;&gt;::type r2;
r1 = r2;  
</pre></blockquote>

<p>
The nested type of <code>ratio_subtract&lt;ratio&lt;2,3&gt;,
ratio&lt;1,3&gt;&gt;</code> could be <code>ratio&lt;3,9&gt;</code> so the compilation
could fail. It could also be <code>ratio&lt;1,3&gt;</code> and the compilation
succeeds.
</p>

<p>
In 21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a> 3 and similar clauses
</p>

<blockquote><p>
3 The nested typedef <code>type</code> shall be a synonym for <code>ratio&lt;T1,
T2&gt;</code> where <code>T1</code> has the value <code>R1::num * R2::den - R2::num *
R1::den</code> and <code>T2</code> has the value <code>R1::den * R2::den</code>.
</p></blockquote>

<p>
the meaning of synonym let think that the result shall be a normalized
<code>ratio</code> equivalent to <code>ratio&lt;T1, T2&gt;</code>, but there is not an
explicit definition of what synonym means in this context.
</p>

<p>
Additionally we should add a typedef for accessing the normalized
<code>ratio</code>, and  change 21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a> to return only this
<em>normalized</em> result.
</p>

<p><i>[
2010 Pittsburgh:
]</i></p>


<blockquote>
<p>
There is no consensus to add the converting copy constructor or converting copy
assignment operator.  However there was consensus to add the typedef.
</p>

<p>
Proposed wording modified.  Original proposed wording preserved here.  Moved to
Review.
</p>

<blockquote class="note">
<p>
Make <code>ratio</code> default constructible, copy-constructible and assignable
from any <code>ratio</code> which has the same reduced form.
</p>

<p>
Add to 21.5.3 <a href="https://wg21.link/ratio.ratio">[ratio.ratio]</a> synopsis
</p>

<blockquote><pre>
template &lt;intmax_t N, intmax_t D = 1&gt;
class ratio {
public:
  static constexpr intmax_t num;
  static constexpr intmax_t den;

  <ins>typedef ratio&lt;num, den&gt; type;</ins>

  <ins>ratio() = default;
  template &lt;intmax_t N2, intmax_t D2&gt;
    ratio(const ratio&lt;N2, D2&gt;&amp;);
  template &lt;intmax_t N2, intmax_t D2&gt;
    ratio&amp; operator=(const ratio&lt;N2, D2&gt;&amp;);</ins>
};
</pre></blockquote>

<p>
Add to 21.5.3 <a href="https://wg21.link/ratio.ratio">[ratio.ratio]</a>:
</p>

<blockquote>
<p>
Two ratio classes <code>ratio&lt;N1,D1&gt;</code> and <code>ratio&lt;N2,D2&gt;</code>
have the same reduced form if <code>ratio&lt;N1,D1&gt;::type</code> is the same
type as <code>ratio&lt;N2,D2&gt;::type</code>
</p>

</blockquote>

<p>
Add a new section: [ratio.cons]
</p>

<blockquote>
<p><b>
Construction and assignment  [ratio.cons]
</b></p>

<pre>
template &lt;intmax_t N2, intmax_t D2&gt;
  ratio(const ratio&lt;N2, D2&gt;&amp; r);
</pre>

<blockquote>
<p>
<i>Effects:</i> Constructs a <code>ratio</code> object.
</p>
<p>
<i>Remarks:</i> This constructor shall not participate in overload resolution
unless <code>r</code> has the same reduced form as <code>*this</code>.
</p>
</blockquote>

<pre>
template &lt;intmax_t N2, intmax_t D2&gt;
  ratio&amp; operator=(const ratio&lt;N2, D2&gt;&amp; r);
</pre>

<blockquote>
<p>
<i>Effects:</i> None.
</p>
<p>
<i>Returns:</i> <code>*this</code>.
</p>
<p>
<i>Remarks:</i> This operator shall not participate in overload resolution
unless <code>r</code> has the same reduced form as <code>*this</code>.
</p>
</blockquote>

</blockquote>

<p>
Change 21.5.4 <a href="https://wg21.link/ratio.arithmetic">[ratio.arithmetic]</a> 
</p>

<blockquote>
<p>
Implementations may use other algorithms to compute these values. If overflow
occurs, a diagnostic shall be issued.
</p>

<pre>
template &lt;class R1, class R2&gt; struct ratio_add {
  typedef <i>see below</i> type;
};
</pre>

<blockquote><p>
The nested typedef <code>type</code> shall be a synonym for <code>ratio&lt;T1,
T2&gt;<ins>::type</ins></code> where <code>T1</code> has the value <code>R1::num *
R2::den + R2::num * R1::den</code> and <code>T2</code> has the value <code>R1::den *
R2::den</code>.
</p></blockquote>

<pre>
template &lt;class R1, class R2&gt; struct ratio_subtract {
  typedef <i>see below</i> type;
};
</pre>

<blockquote><p>
The nested typedef <code>type</code> shall be a synonym for <code>ratio&lt;T1,
T2&gt;<ins>::type</ins></code> where <code>T1</code> has the value <code>R1::num *
R2::den - R2::num * R1::den</code> and <code>T2</code> has the value <code>R1::den *
R2::den</code>.
</p></blockquote>

<pre>
template &lt;class R1, class R2&gt; struct ratio_multiply {
  typedef <i>see below</i> type;
};
</pre>

<blockquote><p>
The nested typedef <code>type</code> shall be a synonym for <code>ratio&lt;T1,
T2&gt;<ins>::type</ins></code> where <code>T1</code> has the value <code>R1::num *
R2::num</code> and <code>T2</code> has the value <code>R1::den * R2::den</code>.
</p></blockquote>

<pre>
template &lt;class R1, class R2&gt; struct ratio_divide {
  typedef <i>see below</i> type;
};
</pre>

<blockquote><p>
The nested typedef <code>type</code> shall be a synonym for <code>ratio&lt;T1,
T2&gt;<ins>::type</ins></code> where <code>T1</code> has the value <code>R1::num *
R2::den</code> and <code>T2</code> has the value <code>R1::den * R2::num</code>.
</p></blockquote>

</blockquote>

</blockquote>

</blockquote>

<p><i>[
2010-03-27 Howard adds:
]</i></p>


<blockquote>
<p>
Daniel brought to my attention the recent addition of the typedef <code>type</code>
to the FCD
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf">N3092</a>:
</p>

<blockquote><pre>
typedef ratio type;
</pre></blockquote>

<p>
This issue was discussed in Pittsburgh, and the decision there was to accept the
typedef as proposed and move to Review.  Unfortunately the issue was accidently
applied to the FCD, and incorrectly.  The FCD version of the typedef refers to
<code>ratio&lt;N, D&gt;</code>, but the typedef is intended to refer to
<code>ratio&lt;num, den&gt;</code> which in general is not the same type.
</p>

<p>
I've updated the wording to diff against
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf">N3092</a>.
</p>

</blockquote>

<p><i>[Batavia: <del>NAD Editorial</del><ins>Resolved</ins> - see rationale below]</i></p>




<p><b>Rationale:</b></p><p>Already fixed in working draft</p>

<p id="res-1281"><b>Proposed resolution:</b></p>
<p>
Add to 21.5.3 <a href="https://wg21.link/ratio.ratio">[ratio.ratio]</a> synopsis
</p>

<blockquote><pre>
template &lt;intmax_t N, intmax_t D = 1&gt;
class ratio {
public:
  static constexpr intmax_t num;
  static constexpr intmax_t den;

  typedef ratio<ins>&lt;num, den&gt;</ins> type;
};
</pre></blockquote>






</body>
</html>
