Add constexpr to some functions in Boost.Rational

[SVN r85454]
This commit is contained in:
Daryle Walker 2013-08-25 08:36:27 +00:00
parent ceee860166
commit d9d55b3245
2 changed files with 51 additions and 24 deletions

View File

@ -21,6 +21,7 @@
// Nickolay Mladenov, for the implementation of operator+=
// Revision History
// 25 Aug 13 Add constexpr qualification wherever possible (Daryle Walker)
// 05 May 12 Reduced use of implicit gcd (Mario Lang)
// 05 Nov 06 Change rational_cast to not depend on division between different
// types (Daryle Walker)
@ -62,7 +63,7 @@
#include <boost/operators.hpp> // for boost::addable etc
#include <cstdlib> // for std::abs
#include <boost/call_traits.hpp> // for boost::call_traits
#include <boost/config.hpp> // for BOOST_NO_STDC_NAMESPACE, BOOST_MSVC
#include <boost/config.hpp> // for BOOST_NO_STDC_NAMESPACE, BOOST_MSVC, etc
#include <boost/detail/workaround.hpp> // for BOOST_WORKAROUND
#include <boost/assert.hpp> // for BOOST_ASSERT
#include <boost/math/common_factor_rt.hpp> // for boost::math::gcd, lcm
@ -134,8 +135,12 @@ class rational :
typedef IntType (helper::* bool_type)[2];
public:
// Component type
typedef IntType int_type;
BOOST_CONSTEXPR
rational() : num(0), den(1) {}
BOOST_CONSTEXPR
rational(param_type n) : num(n), den(1) {}
rational(param_type n, param_type d) : num(n), den(d) { normalize(); }
@ -148,7 +153,9 @@ public:
rational& assign(param_type n, param_type d);
// Access to representation
BOOST_CONSTEXPR
IntType numerator() const { return num; }
BOOST_CONSTEXPR
IntType denominator() const { return den; }
// Arithmetic assignment operators
@ -167,6 +174,7 @@ public:
const rational& operator--() { num -= den; return *this; }
// Operator not
BOOST_CONSTEXPR
bool operator!() const { return !num; }
// Boolean conversion
@ -178,6 +186,7 @@ public:
#pragma parse_mfunc_templ off
#endif
BOOST_CONSTEXPR
operator bool_type() const { return operator !() ? 0 : &helper::parts; }
#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
@ -186,10 +195,12 @@ public:
// Comparison operators
bool operator< (const rational& r) const;
BOOST_CONSTEXPR
bool operator== (const rational& r) const;
bool operator< (param_type i) const;
bool operator> (param_type i) const;
BOOST_CONSTEXPR
bool operator== (param_type i) const;
private:
@ -218,6 +229,7 @@ inline rational<IntType>& rational<IntType>::assign(param_type n, param_type d)
// Unary plus and minus
template <typename IntType>
BOOST_CONSTEXPR
inline rational<IntType> operator+ (const rational<IntType>& r)
{
return r;
@ -474,12 +486,14 @@ bool rational<IntType>::operator> (param_type i) const
}
template <typename IntType>
BOOST_CONSTEXPR
inline bool rational<IntType>::operator== (const rational<IntType>& r) const
{
return ((num == r.num) && (den == r.den));
}
template <typename IntType>
BOOST_CONSTEXPR
inline bool rational<IntType>::operator== (param_type i) const
{
return ((den == IntType(1)) && (num == i));
@ -573,6 +587,7 @@ std::ostream& operator<< (std::ostream& os, const rational<IntType>& r)
// Type conversion
template <typename T, typename IntType>
BOOST_CONSTEXPR
inline T rational_cast(
const rational<IntType>& src BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
{

View File

@ -55,9 +55,9 @@ public:
typedef I int_type;
// Constructors
rational(); // Zero
rational(I n); // Equal to n/1
rational(I n, I d); // General case (n/d)
constexpr rational(); // Zero
constexpr rational(I n); // Equal to n/1
rational(I n, I d); // General case (n/d)
// Normal copy constructors and assignment operators
@ -68,8 +68,8 @@ public:
rational&amp; assign(I n, I d);
// Representation
I numerator() const;
I denominator() const;
constexpr I numerator() const;
constexpr I denominator() const;
// In addition to the following operators, all of the "obvious" derived
// operators are available - see <a href="../utility/operators.htm">operators.hpp</a>
@ -91,24 +91,24 @@ public:
const rational&amp; operator--();
// Operator not
bool operator!() const;
constexpr bool operator!() const;
// Boolean conversion
operator bool_type() const;
constexpr operator bool_type() const;
// Comparison operators
bool operator&lt; (const rational&amp; r) const;
bool operator== (const rational&amp; r) const;
bool operator&lt; (const rational&amp; r) const;
constexpr bool operator== (const rational&amp; r) const;
// Comparison with integers
bool operator&lt; (I i) const;
bool operator&gt; (I i) const;
bool operator== (I i) const;
bool operator&lt; (I i) const;
bool operator&gt; (I i) const;
constexpr bool operator== (I i) const;
};
// Unary operators
template &lt;typename I&gt; rational&lt;I&gt; operator+ (const rational&lt;I&gt;&amp; r);
template &lt;typename I&gt; rational&lt;I&gt; operator- (const rational&lt;I&gt;&amp; r);
template &lt;typename I&gt; constexpr rational&lt;I&gt; operator+ (const rational&lt;I&gt;&amp; r);
template &lt;typename I&gt; rational&lt;I&gt; operator- (const rational&lt;I&gt;&amp; r);
// Reversed order operators for - and / between (types convertible to) I and rational
template &lt;typename I, typename II&gt; inline rational&lt;I&gt; operator- (II i, const rational&lt;I&gt;&amp; r);
@ -122,7 +122,7 @@ template &lt;typename I&gt; std::istream&amp; operator&gt;&gt; (std::istream&amp
template &lt;typename I&gt; std::ostream&amp; operator&lt;&lt; (std::ostream&amp; os, const rational&lt;I&gt;&amp; r);
// Type conversion
template &lt;typename T, typename I&gt; T rational_cast (const rational&lt;I&gt;&amp; r);
template &lt;typename T, typename I&gt; constexpr T rational_cast (const rational&lt;I&gt;&amp; r);
</pre>
<h2><a name="Rationale">Rationale</a></h2>
@ -167,8 +167,8 @@ these bounds, overflow occurs and the results are undefined.
<p>
The rational number class is a template to allow the programmer to control the
overflow behaviour somewhat. If an unlimited precision integer type is
available, rational numbers based on it will never overflow and will provide
exact calculations in all circumstances.
available, rational numbers based on it will never overflow (modulo resource
limits) and will provide exact calculations in all circumstances.
<h2><a name="Integer Type Requirements">Integer Type Requirements</a></h2>
@ -289,6 +289,11 @@ of course.) The components are stored in normalized form.
rational&lt;I&gt; r2(n, d);
</pre>
<p>The no- and single-argument constructors are marked as <code>constexpr</code>,
making them viable in constant-expressions when the initializers (if any) are
also constant expressions (and the necessary operations from the underlying
integer type are <code>constexpr</code>-enabled).
<p>The single-argument constructor is <em>not</em> declared as explicit, so
there is an implicit conversion from the underlying integer type to the
rational type.
@ -309,6 +314,9 @@ class. These include:
&lt;= &gt;=
</pre>
<p>So far, only <code>operator ==</code> and unary <code>operator +</code> are
<code>constexpr</code>-enabled.
<h3><a name="Input and Output">Input and Output</a></h3>
Input and output operators <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt>
are provided. The external representation of a rational is
@ -356,6 +364,9 @@ denominator (in the target floating point type) does not evaluate correctly.
operations should behave "sensibly". If these constraints cannot be met, a
separate user-defined conversion will be more appropriate.
<p>Boolean conversion, <tt>rational_cast</tt>, and the explicitly written
<code>operator !</code> are <code>constexpr</code>-enabled.
<p><em>Implementation note:</em>
<p>The implementation of the rational_cast function was
@ -376,6 +387,7 @@ href="#Integer%20Type%20Requirements">Integer Type Requirements</a>.)
<h3><a name="Numerator and Denominator">Numerator and Denominator</a></h3>
Finally, access to the internal representation of rationals is provided by
the two member functions <tt>numerator()</tt> and <tt>denominator()</tt>.
These functions are <code>constexpr</code>-enabled.
<p>These functions allow user code to implement any additional required
functionality. In particular, it should be noted that there may be cases where
@ -669,13 +681,13 @@ on the boost list in January 2001.
be used in the same Boolean contexts as the built-in numeric types, in December
2005.
<p>Revised November 5, 2006</p>
<p>Revised August 25, 2013</p>
<p>&copy; Copyright Paul Moore 1999-2001; &copy; Daryle Walker 2005. Permission
to copy, use, modify, sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided &quot;as
is&quot; without express or implied warranty, and with no claim as to its
suitability for any purpose.</p>
<p>&copy; Copyright Paul Moore 1999-2001; &copy; Daryle Walker 2005, 2013.
Permission to copy, use, modify, sell and distribute this document is granted
provided this copyright notice appears in all copies. This document is provided
&quot;as is&quot; without express or implied warranty, and with no claim as to
its suitability for any purpose.</p>
<!-- boostinspect:nolicense (can't find Paul Moore to change license) -->
</body>
</html>