Added MPL-compatible variant of the processor-optimized integer template

[SVN r47452]
This commit is contained in:
Daryle Walker
2008-07-15 18:56:59 +00:00
parent 55e1796c7a
commit f27ad7b337
4 changed files with 66 additions and 32 deletions

View File

@ -7,7 +7,8 @@
// See http://www.boost.org/libs/integer for documentation.
// Revision History
// 15 Jul 08 Added exact-integer templates. (Daryle Walker)
// 15 Jul 08 Added exact-integer templates; added MPL-compatible variant of
// processor-optimized integer template. (Daryle Walker)
// 14 Jul 08 Added extended-integer support. (Daryle Walker)
// 13 Jul 08 Redid implmentation. (Daryle Walker)
// 22 Sep 01 Added value-based integer templates. (Daryle Walker)
@ -24,6 +25,7 @@
#include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
#include <boost/integer_traits.hpp> // for boost::integer_traits
#include <boost/limits.hpp> // for std::numeric_limits
#include <boost/utility/enable_if.hpp> // for boost::enable_if_c
#include <climits> // for UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, etc.
@ -32,10 +34,21 @@ namespace boost
// integer template mapping a type to its processor-optimized analog -----//
// Some types can be handled better by the processor than others. This
// template metafunction should map various built-in integral types to
// the processor's perferred type for the given type's value range
template < typename BaseInt >
struct fast_integral
{
typedef BaseInt type;
};
// Platform-specific specializations should go here.
// fast integers from least integers
// int_fast_t<> works correctly for unsigned too, in spite of the name.
template< typename LeastInt >
struct int_fast_t { typedef LeastInt fast; }; // imps may specialize
struct int_fast_t { typedef typename fast_integral<LeastInt>::type fast; };
namespace detail
{

View File

@ -84,6 +84,9 @@ template < >
// From <boost/integer.hpp> ------------------------------------------------//
template < typename BaseInt >
struct fast_integral;
template < typename LeastInt >
struct int_fast_t;

View File

@ -40,10 +40,27 @@ is particularly useful for solving generic programming problems.</p>
namespace boost
{
// fast integers from least integers
template&lt; typename BaseInt &gt;
struct fast_integral
{
typedef <em>implementation_supplied</em> type;
};
template&lt; typename LeastInt &gt;
struct int_fast_t
{
typedef <em>implementation_supplied</em> fast;
typedef typename fast_integral&lt;LeastInt&gt;::type fast;
};
// MPL-compatible
template&lt; int Bits, typename Signedness &gt;
struct exact_integral
{
static bool const is_specialized = <em>implementation_supplied</em>;
static bool const is_signed = <em>implementation_supplied</em>;
static int const bit_count = Bits;
typedef <em>implementation_supplied</em> type;
};
// signed
@ -57,7 +74,7 @@ namespace boost
template&lt; int Bits &gt;
struct int_exact_t
{
typedef <em>implementation_supplied</em> exact;
typedef typename exact_integral&lt;Bits, signed&gt;::type exact;
};
// unsigned
@ -71,7 +88,7 @@ namespace boost
template&lt; int Bits &gt;
struct uint_exact_t
{
typedef <em>implementation_supplied</em> exact;
typedef typename exact_integral&lt;Bits, unsigned&gt;::type exact;
};
// signed
@ -96,31 +113,25 @@ namespace boost
typedef <em>implementation_supplied</em> least;
typedef int_fast_t&lt;least&gt;::fast fast;
};
// MPL-compatible
template&lt; int Bits, typename Signedness &gt;
struct exact_integral
{
static bool const is_specialized = <em>implementation_supplied</em>;
static bool const is_signed = <em>implementation_supplied</em>;
static int const bit_count = Bits;
typedef <em>implementation_supplied</em> type;
};
} // namespace boost
</pre></blockquote>
<h2><a name="easy">Processor-Optimized Types</a></h2>
<p>The <code>int_fast_t</code> class template maps its input type to the
<p>The <code>fast_integral</code> class template maps its input type to the
next-largest type that the processor can manipulate the easiest, or to
itself if the input type is already an easy-to-manipulate type. For
instance, processing a bunch of <code>char</code> objects may go faster
if they were converted to <code>int</code> objects before processing.
The input type, passed as the only template parameter, must be a
built-in integral type, except <code>bool</code>. Unsigned integral
types can be used, as well as signed integral types, despite the name.
The output type is given as the class member <code>fast</code>.</p>
The input type, passed as the only template parameter, can be any built-in
integral type besides <code>bool</code>. The output type is given as the class
member <code>type</code>.</p>
<p>The <code>int_fast_t</code> class template is the classic meta-function for
this operation. Despite the name, it works for unsigned integral types just
like it works for the signed integral types. The output type is given as the
class member <code>fast</code>, defined to be the same as the corresponding
result from the <code>fast_integral</code> meta-function.</p>
<p><strong>Implementation Notes</strong><br>
By default, the output type is identical to the input type. Eventually,
@ -282,7 +293,7 @@ struct <var>name</var>
<td><code>type</code></td>
<td><code>is_specialized == true</code></td>
<td>The meta-function's result. It appears only if the input parameters
satisfy the template's requirements. It's presence, or lack thereof,
satisfy the template's requirements. Its presence, or lack thereof,
enables &quot;Substitution Failure Is Not An Error&quot; (SFINAE)
techniques, instead of a hard compiler diagnostic.</td>
</tr>

View File

@ -8,7 +8,8 @@
// See http://www.boost.org/libs/integer for documentation.
// Revision History
// 15 Jul 08 Added exact-integer templates. (Daryle Walker)
// 15 Jul 08 Added exact-integer templates; added MPL-compatible variant of
// processor-optimized integer template. (Daryle Walker)
// 14 Jul 08 Improved testing of processor-optimized integer template; added
// extended-integer support. (Daryle Walker)
// 13 Jul 08 Modernized tests w/ MPL instead of giant macros (Daryle Walker)
@ -69,15 +70,15 @@
// If specializations have not already been done, then we can confirm
// the effects of the "fast" types by making a specialization. If there
// the effects of the fast types by making a specialization. If there
// is a specialization for "short," make sure that CONTROL_FAST_SHORT
// is set to a type distinct from "short" and the default implementation.
namespace boost
{
template < >
struct int_fast_t< short >
struct fast_integral< short >
{
typedef CONTROL_FAST_SHORT fast;
typedef CONTROL_FAST_SHORT type;
};
}
@ -273,8 +274,10 @@ BOOST_AUTO_TEST_CASE( fast_type_test )
{
#ifndef BOOST_NO_USING_TEMPLATE
using std::numeric_limits;
using boost::is_same;
#else
using namespace std;
using namespace boost;
#endif
typedef short least_type;
@ -282,8 +285,12 @@ BOOST_AUTO_TEST_CASE( fast_type_test )
typedef numeric_limits<least_type> least_limits;
typedef numeric_limits<fast_type> fast_limits;
BOOST_MPL_ASSERT_RELATION( (boost::is_same<least_type, fast_type>::value),
==, false );
typedef boost::fast_integral<least_type>::type real_fast_type;
BOOST_MPL_ASSERT_RELATION( (is_same<least_type, fast_type>::value), ==,
false );
BOOST_MPL_ASSERT_RELATION( (is_same<fast_type, real_fast_type>::value), ==,
true );
BOOST_MPL_ASSERT_RELATION( fast_limits::is_specialized, ==, true );
BOOST_MPL_ASSERT_RELATION( fast_limits::is_signed &&
fast_limits::is_bounded, ==, true );