mirror of
https://github.com/boostorg/type_traits.git
synced 2025-07-29 20:17:21 +02:00
Added new type traits files.
[SVN r9238]
This commit is contained in:
590
c++_type_traits.htm
Normal file
590
c++_type_traits.htm
Normal file
@ -0,0 +1,590 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
||||
<title>C++ Type traits</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
|
||||
|
||||
<h2 align="center">C++ Type traits</h2>
|
||||
|
||||
<p align="center"><em>by John Maddock and Steve Cleary</em></p>
|
||||
|
||||
<p align="center"><em>This is the draft version of an article
|
||||
that appeared in the October 2000 issue of </em><a
|
||||
href="http://www.ddj.com"><em>Dr Dobb's Journal</em></a></p>
|
||||
|
||||
<p>Generic programming (writing code which works with any data
|
||||
type meeting a set of requirements) has become the method of
|
||||
choice for providing reusable code. However, there are times in
|
||||
generic programming when "generic" just isn't good
|
||||
enough - sometimes the differences between types are too large
|
||||
for an efficient generic implementation. This is when the traits
|
||||
technique becomes important - by encapsulating those properties
|
||||
that need to be considered on a type by type basis inside a
|
||||
traits class, we can minimise the amount of code that has to
|
||||
differ from one type to another, and maximise the amount of
|
||||
generic code.</p>
|
||||
|
||||
<p>Consider an example: when working with character strings, one
|
||||
common operation is to determine the length of a null terminated
|
||||
string. Clearly it's possible to write generic code that can do
|
||||
this, but it turns out that there are much more efficient methods
|
||||
available: for example, the C library functions <font size="2"
|
||||
face="Courier New">strlen</font> and <font size="2"
|
||||
face="Courier New">wcslen</font> are usually written in assembler,
|
||||
and with suitable hardware support can be considerably faster
|
||||
than a generic version written in C++. The authors of the C++
|
||||
standard library realised this, and abstracted the properties of <font
|
||||
size="2" face="Courier New">char</font> and <font size="2"
|
||||
face="Courier New">wchar_t</font> into the class <font size="2"
|
||||
face="Courier New">char_traits</font>. Generic code that works
|
||||
with character strings can simply use <font size="2"
|
||||
face="Courier New">char_traits<>::length</font> to
|
||||
determine the length of a null terminated string, safe in the
|
||||
knowledge that specialisations of <font size="2"
|
||||
face="Courier New">char_traits</font> will use the most
|
||||
appropriate method available to them.</p>
|
||||
|
||||
<h4>Type traits</h4>
|
||||
|
||||
<p>Class <font size="2" face="Courier New">char_traits</font> is
|
||||
a classic example of a collection of type specific properties
|
||||
wrapped up in a single class - what Nathan Myers termed a <i>baggage
|
||||
class</i>[1]. In the Boost type-traits library, we[2] have
|
||||
written a set of very specific traits classes, each of which
|
||||
encapsulate a single trait from the C++ type system; for example,
|
||||
is a type a pointer or a reference type? Or does a type have a
|
||||
trivial constructor, or a const-qualifier? The type-traits
|
||||
classes share a unified design: each class has a single member <i>value</i>,
|
||||
a compile-time constant that is true if the type has the
|
||||
specified property, and false otherwise. As we will show, these
|
||||
classes can be used in generic programming to determine the
|
||||
properties of a given type and introduce optimisations that are
|
||||
appropriate for that case.</p>
|
||||
|
||||
<p>The type-traits library also contains a set of classes that
|
||||
perform a specific transformation on a type; for example, they
|
||||
can remove a top-level const or volatile qualifier from a type.
|
||||
Each class that performs a transformation defines a single
|
||||
typedef-member <i>type</i> that is the result of the
|
||||
transformation. All of the type-traits classes are defined inside
|
||||
namespace <font size="2" face="Courier New">boost</font>; for
|
||||
brevity, namespace-qualification is omitted in most of the code
|
||||
samples given.</p>
|
||||
|
||||
<h4>Implementation</h4>
|
||||
|
||||
<p>There are far too many separate classes contained in the type-traits
|
||||
library to give a full implementation here - see the source code
|
||||
in the Boost library for the full details - however, most of the
|
||||
implementation is fairly repetitive anyway, so here we will just
|
||||
give you a flavour for how some of the classes are implemented.
|
||||
Beginning with possibly the simplest class in the library, is_void<T>
|
||||
has a member <i>value</i> that is true only if T is void.</p>
|
||||
|
||||
<pre>template <typename T>
|
||||
struct is_void
|
||||
{ static const bool value = false; };
|
||||
|
||||
template <>
|
||||
struct is_void<void>
|
||||
{ static const bool value = true; };</pre>
|
||||
|
||||
<p>Here we define a primary version of the template class <font
|
||||
size="2" face="Courier New">is_void</font>, and provide a full-specialisation
|
||||
when T is void. While full specialisation of a template class is
|
||||
an important technique, sometimes we need a solution that is
|
||||
halfway between a fully generic solution, and a full
|
||||
specialisation. This is exactly the situation for which the
|
||||
standards committee defined partial template-class specialisation.
|
||||
As an example, consider the class boost::is_pointer<T>:
|
||||
here we needed a primary version that handles all the cases where
|
||||
T is not a pointer, and a partial specialisation to handle all
|
||||
the cases where T is a pointer:</p>
|
||||
|
||||
<pre>template <typename T>
|
||||
struct is_pointer
|
||||
{ static const bool value = false; };
|
||||
|
||||
template <typename T>
|
||||
struct is_pointer<T*>
|
||||
{ static const bool value = true; };</pre>
|
||||
|
||||
<p>The syntax for partial specialisation is somewhat arcane and
|
||||
could easily occupy an article in its own right; like full
|
||||
specialisation, in order to write a partial specialisation for a
|
||||
class, you must first declare the primary template. The partial
|
||||
specialisation contains an extra <…> after the class
|
||||
name that contains the partial specialisation parameters; these
|
||||
define the types that will bind to that partial specialisation
|
||||
rather than the default template. The rules for what can appear
|
||||
in a partial specialisation are somewhat convoluted, but as a
|
||||
rule of thumb if you can legally write two function overloads of
|
||||
the form:</p>
|
||||
|
||||
<pre>void foo(T);
|
||||
void foo(U);</pre>
|
||||
|
||||
<p>Then you can also write a partial specialisation of the form:</p>
|
||||
|
||||
<pre>template <typename T>
|
||||
class c{ /*details*/ };
|
||||
|
||||
template <typename T>
|
||||
|
||||
class c<U>{ /*details*/ };</pre>
|
||||
|
||||
<p>This rule is by no means foolproof, but it is reasonably
|
||||
simple to remember and close enough to the actual rule to be
|
||||
useful for everyday use.</p>
|
||||
|
||||
<p>As a more complex example of partial specialisation consider
|
||||
the class remove_bounds<T>. This class defines a single
|
||||
typedef-member <i>type</i> that is the same type as T but with
|
||||
any top-level array bounds removed; this is an example of a
|
||||
traits class that performs a transformation on a type:</p>
|
||||
|
||||
<pre>template <typename T>
|
||||
struct remove_bounds
|
||||
{ typedef T type; };
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct remove_bounds<T[N]>
|
||||
{ typedef T type; };</pre>
|
||||
|
||||
<p>The aim of remove_bounds is this: imagine a generic algorithm
|
||||
that is passed an array type as a template parameter, <font
|
||||
size="2" face="Courier New">remove_bounds</font> provides a means
|
||||
of determining the underlying type of the array. For example <code>remove_bounds<int[4][5]>::type</code>
|
||||
would evaluate to the type <code>int[5]</code>. This example also
|
||||
shows that the number of template parameters in a partial
|
||||
specialisation does not have to match the number in the default
|
||||
template. However, the number of parameters that appear after the
|
||||
class name do have to match the number and type of the parameters
|
||||
in the default template.</p>
|
||||
|
||||
<h4>Optimised copy</h4>
|
||||
|
||||
<p>As an example of how the type traits classes can be used,
|
||||
consider the standard library algorithm copy:</p>
|
||||
|
||||
<pre>template<typename Iter1, typename Iter2>
|
||||
Iter2 copy(Iter1 first, Iter1 last, Iter2 out);</pre>
|
||||
|
||||
<p>Obviously, there's no problem writing a generic version of
|
||||
copy that works for all iterator types Iter1 and Iter2; however,
|
||||
there are some circumstances when the copy operation can best be
|
||||
performed by a call to <font size="2" face="Courier New">memcpy</font>.
|
||||
In order to implement copy in terms of <font size="2"
|
||||
face="Courier New">memcpy</font> all of the following conditions
|
||||
need to be met:</p>
|
||||
|
||||
<ul>
|
||||
<li>Both of the iterator types Iter1 and Iter2 must be
|
||||
pointers.</li>
|
||||
<li>Both Iter1 and Iter2 must point to the same type -
|
||||
excluding <font size="2" face="Courier New">const</font>
|
||||
and <font size="2" face="Courier New">volatile</font>-qualifiers.</li>
|
||||
<li>The type pointed to by Iter1 must have a trivial
|
||||
assignment operator.</li>
|
||||
</ul>
|
||||
|
||||
<p>By trivial assignment operator we mean that the type is either
|
||||
a scalar type[3] or:</p>
|
||||
|
||||
<ul>
|
||||
<li>The type has no user defined assignment operator.</li>
|
||||
<li>The type does not have any data members that are
|
||||
references.</li>
|
||||
<li>All base classes, and all data member objects must have
|
||||
trivial assignment operators.</li>
|
||||
</ul>
|
||||
|
||||
<p>If all these conditions are met then a type can be copied
|
||||
using <font size="2" face="Courier New">memcpy</font> rather than
|
||||
using a compiler generated assignment operator. The type-traits
|
||||
library provides a class <i>has_trivial_assign</i>, such that <code>has_trivial_assign<T>::value</code>
|
||||
is true only if T has a trivial assignment operator. This class
|
||||
"just works" for scalar types, but has to be explicitly
|
||||
specialised for class/struct types that also happen to have a
|
||||
trivial assignment operator. In other words if <i>has_trivial_assign</i>
|
||||
gives the wrong answer, it will give the "safe" wrong
|
||||
answer - that trivial assignment is not allowable.</p>
|
||||
|
||||
<p>The code for an optimised version of copy that uses <font
|
||||
size="2" face="Courier New">memcpy</font> where appropriate is
|
||||
given in listing 1. The code begins by defining a template class <i>copier</i>,
|
||||
that takes a single Boolean template parameter, and has a static
|
||||
template member function <font size="2" face="Courier New">do_copy</font>
|
||||
which performs the generic version of <font size="2">copy</font>
|
||||
(in other words the "slow but safe version"). Following
|
||||
that there is a specialisation for <i>copier<true></i>:
|
||||
again this defines a static template member function <font
|
||||
size="2" face="Courier New">do_copy</font>, but this version uses
|
||||
memcpy to perform an "optimised" copy.</p>
|
||||
|
||||
<p>In order to complete the implementation, what we need now is a
|
||||
version of copy, that calls <code>copier<true>::do_copy</code>
|
||||
if it is safe to use <font size="2" face="Courier New">memcpy</font>,
|
||||
and otherwise calls <code>copier<false>::do_copy</code> to
|
||||
do a "generic" copy. This is what the version in
|
||||
listing 1 does. To understand how the code works look at the code
|
||||
for <font size="2" face="Courier New">copy</font> and consider
|
||||
first the two typedefs <i>v1_t</i> and <i>v2_t</i>. These use <code>std::iterator_traits<Iter1>::value_type</code>
|
||||
to determine what type the two iterators point to, and then feed
|
||||
the result into another type-traits class <i>remove_cv</i> that
|
||||
removes the top-level const-volatile-qualifiers: this will allow
|
||||
copy to compare the two types without regard to const- or
|
||||
volatile-qualifiers. Next, <font size="2" face="Courier New">copy</font>
|
||||
declares an enumerated value <i>can_opt</i> that will become the
|
||||
template parameter to copier - declaring this here as a constant
|
||||
is really just a convenience - the value could be passed directly
|
||||
to class <font size="2" face="Courier New">copier</font>. The
|
||||
value of <i>can_opt</i> is computed by verifying that all of the
|
||||
following are true:</p>
|
||||
|
||||
<ul>
|
||||
<li>first that the two iterators point to the same type by
|
||||
using a type-traits class <i>is_same</i>.</li>
|
||||
<li>Then that both iterators are real pointers - using the
|
||||
class <i>is_pointer</i> described above.</li>
|
||||
<li>Finally that the pointed-to types have a trivial
|
||||
assignment operator using <i>has_trivial_assign</i>.</li>
|
||||
</ul>
|
||||
|
||||
<p>Finally we can use the value of <i>can_opt</i> as the template
|
||||
argument to copier - this version of copy will now adapt to
|
||||
whatever parameters are passed to it, if its possible to use <font
|
||||
size="2" face="Courier New">memcpy</font>, then it will do so,
|
||||
otherwise it will use a generic copy.</p>
|
||||
|
||||
<h4>Was it worth it?</h4>
|
||||
|
||||
<p>It has often been repeated in these columns that "premature
|
||||
optimisation is the root of all evil" [4]. So the question
|
||||
must be asked: was our optimisation premature? To put this in
|
||||
perspective the timings for our version of copy compared a
|
||||
conventional generic copy[5] are shown in table 1.</p>
|
||||
|
||||
<p>Clearly the optimisation makes a difference in this case; but,
|
||||
to be fair, the timings are loaded to exclude cache miss effects
|
||||
- without this accurate comparison between algorithms becomes
|
||||
difficult. However, perhaps we can add a couple of caveats to the
|
||||
premature optimisation rule:</p>
|
||||
|
||||
<ul>
|
||||
<li>If you use the right algorithm for the job in the first
|
||||
place then optimisation will not be required; in some
|
||||
cases, <font size="2" face="Courier New">memcpy</font> is
|
||||
the right algorithm.</li>
|
||||
<li>If a component is going to be reused in many places by
|
||||
many people then optimisations may well be worthwhile
|
||||
where they would not be so for a single case - in other
|
||||
words, the likelihood that the optimisation will be
|
||||
absolutely necessary somewhere, sometime is that much
|
||||
higher. Just as importantly the perceived value of the
|
||||
stock implementation will be higher: there is no point
|
||||
standardising an algorithm if users reject it on the
|
||||
grounds that there are better, more heavily optimised
|
||||
versions available.</li>
|
||||
</ul>
|
||||
|
||||
<h4>Table 1: Time taken to copy 1000 elements using copy<const
|
||||
T*, T*> (times in micro-seconds)</h4>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="529">
|
||||
<tr>
|
||||
<td valign="top" width="33%"><p align="center">Version</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">T</p>
|
||||
</td>
|
||||
<td valign="top" width="33%"><p align="center">Time</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="33%">"Optimised" copy</td>
|
||||
<td valign="top" width="33%">char</td>
|
||||
<td valign="top" width="33%">0.99</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="33%">Conventional copy</td>
|
||||
<td valign="top" width="33%">char</td>
|
||||
<td valign="top" width="33%">8.07</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="33%">"Optimised" copy</td>
|
||||
<td valign="top" width="33%">int</td>
|
||||
<td valign="top" width="33%">2.52</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="33%">Conventional copy</td>
|
||||
<td valign="top" width="33%">int</td>
|
||||
<td valign="top" width="33%">8.02</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h4>Pair of References</h4>
|
||||
|
||||
<p>The optimised copy example shows how type traits may be used
|
||||
to perform optimisation decisions at compile-time. Another
|
||||
important usage of type traits is to allow code to compile that
|
||||
otherwise would not do so unless excessive partial specialization
|
||||
is used. This is possible by delegating partial specialization to
|
||||
the type traits classes. Our example for this form of usage is a
|
||||
pair that can hold references [6].</p>
|
||||
|
||||
<p>First, let us examine the definition of "std::pair",
|
||||
omitting the comparision operators, default constructor, and
|
||||
template copy constructor for simplicity:</p>
|
||||
|
||||
<pre>template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
pair(const T1 & nfirst, const T2 & nsecond)
|
||||
:first(nfirst), second(nsecond) { }
|
||||
};</pre>
|
||||
|
||||
<p>Now, this "pair" cannot hold references as it
|
||||
currently stands, because the constructor would require taking a
|
||||
reference to a reference, which is currently illegal [7]. Let us
|
||||
consider what the constructor's parameters would have to be in
|
||||
order to allow "pair" to hold non-reference types,
|
||||
references, and constant references:</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="638">
|
||||
<tr>
|
||||
<td valign="top" width="50%">Type of "T1"</td>
|
||||
<td valign="top" width="50%">Type of parameter to
|
||||
initializing constructor</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>T</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%"><pre>const T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>T &</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%"><pre>T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="50%"><pre>const T &</pre>
|
||||
</td>
|
||||
<td valign="top" width="50%"><pre>const T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>A little familiarity with the type traits classes allows us to
|
||||
construct a single mapping that allows us to determine the type
|
||||
of parameter from the type of the contained class. The type
|
||||
traits classes provide a transformation "add_reference",
|
||||
which adds a reference to its type, unless it is already a
|
||||
reference.</p>
|
||||
|
||||
<table border="1" cellpadding="7" cellspacing="1" width="580">
|
||||
<tr>
|
||||
<td valign="top" width="21%">Type of "T1"</td>
|
||||
<td valign="top" width="27%">Type of "const T1"</td>
|
||||
<td valign="top" width="53%">Type of "add_reference<const
|
||||
T1>::type"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="21%"><pre>T</pre>
|
||||
</td>
|
||||
<td valign="top" width="27%"><pre>const T</pre>
|
||||
</td>
|
||||
<td valign="top" width="53%"><pre>const T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="21%"><pre>T &</pre>
|
||||
</td>
|
||||
<td valign="top" width="27%"><pre>T & [8]</pre>
|
||||
</td>
|
||||
<td valign="top" width="53%"><pre>T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="21%"><pre>const T &</pre>
|
||||
</td>
|
||||
<td valign="top" width="27%"><pre>const T &</pre>
|
||||
</td>
|
||||
<td valign="top" width="53%"><pre>const T &</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>This allows us to build a primary template definition for
|
||||
"pair" that can contain non-reference types, reference
|
||||
types, and constant reference types:</p>
|
||||
|
||||
<pre>template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
pair(boost::add_reference<const T1>::type nfirst,
|
||||
boost::add_reference<const T2>::type nsecond)
|
||||
:first(nfirst), second(nsecond) { }
|
||||
};</pre>
|
||||
|
||||
<p>Add back in the standard comparision operators, default
|
||||
constructor, and template copy constructor (which are all the
|
||||
same), and you have a std::pair that can hold reference types!</p>
|
||||
|
||||
<p>This same extension <i>could</i> have been done using partial
|
||||
template specialization of "pair", but to specialize
|
||||
"pair" in this way would require three partial
|
||||
specializations, plus the primary template. Type traits allows us
|
||||
to define a single primary template that adjusts itself auto-magically
|
||||
to any of these partial specializations, instead of a brute-force
|
||||
partial specialization approach. Using type traits in this
|
||||
fashion allows programmers to delegate partial specialization to
|
||||
the type traits classes, resulting in code that is easier to
|
||||
maintain and easier to understand.</p>
|
||||
|
||||
<h4>Conclusion</h4>
|
||||
|
||||
<p>We hope that in this article we have been able to give you
|
||||
some idea of what type-traits are all about. A more complete
|
||||
listing of the available classes are in the boost documentation,
|
||||
along with further examples using type traits. Templates have
|
||||
enabled C++ uses to take the advantage of the code reuse that
|
||||
generic programming brings; hopefully this article has shown that
|
||||
generic programming does not have to sink to the lowest common
|
||||
denominator, and that templates can be optimal as well as generic.</p>
|
||||
|
||||
<h4>Acknowledgements</h4>
|
||||
|
||||
<p>The authors would like to thank Beman Dawes and Howard Hinnant
|
||||
for their helpful comments when preparing this article.</p>
|
||||
|
||||
<h4>References</h4>
|
||||
|
||||
<ol>
|
||||
<li>Nathan C. Myers, C++ Report, June 1995.</li>
|
||||
<li>The type traits library is based upon contributions by
|
||||
Steve Cleary, Beman Dawes, Howard Hinnant and John
|
||||
Maddock: it can be found at www.boost.org.</li>
|
||||
<li>A scalar type is an arithmetic type (i.e. a built-in
|
||||
integer or floating point type), an enumeration type, a
|
||||
pointer, a pointer to member, or a const- or volatile-qualified
|
||||
version of one of these types.</li>
|
||||
<li>This quote is from Donald Knuth, ACM Computing Surveys,
|
||||
December 1974, pg 268.</li>
|
||||
<li>The test code is available as part of the boost utility
|
||||
library (see algo_opt_examples.cpp), the code was
|
||||
compiled with gcc 2.95 with all optimisations turned on,
|
||||
tests were conducted on a 400MHz Pentium II machine
|
||||
running Microsoft Windows 98.</li>
|
||||
<li>John Maddock and Howard Hinnant have submitted a "compressed_pair"
|
||||
library to Boost, which uses a technique similar to the
|
||||
one described here to hold references. Their pair also
|
||||
uses type traits to determine if any of the types are
|
||||
empty, and will derive instead of contain to conserve
|
||||
space -- hence the name "compressed".</li>
|
||||
<li>This is actually an issue with the C++ Core Language
|
||||
Working Group (issue #106), submitted by Bjarne
|
||||
Stroustrup. The tentative resolution is to allow a "reference
|
||||
to a reference to T" to mean the same thing as a
|
||||
"reference to T", but only in template
|
||||
instantiation, in a method similar to multiple cv-qualifiers.</li>
|
||||
<li>For those of you who are wondering why this shouldn't be
|
||||
const-qualified, remember that references are always
|
||||
implicitly constant (for example, you can't re-assign a
|
||||
reference). Remember also that "const T &"
|
||||
is something completely different. For this reason, cv-qualifiers
|
||||
on template type arguments that are references are
|
||||
ignored.</li>
|
||||
</ol>
|
||||
|
||||
<h2>Listing 1</h2>
|
||||
|
||||
<pre>namespace detail{
|
||||
|
||||
template <bool b>
|
||||
struct copier
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2 do_copy(I1 first,
|
||||
I1 last, I2 out);
|
||||
};
|
||||
|
||||
template <bool b>
|
||||
template<typename I1, typename I2>
|
||||
I2 copier<b>::do_copy(I1 first,
|
||||
I1 last,
|
||||
I2 out)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*out = *first;
|
||||
++out;
|
||||
++first;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct copier<true>
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2* do_copy(I1* first, I1* last, I2* out)
|
||||
{
|
||||
memcpy(out, first, (last-first)*sizeof(I2));
|
||||
return out+(last-first);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
typedef typename
|
||||
boost::remove_cv<
|
||||
typename std::iterator_traits<I1>
|
||||
::value_type>::type v1_t;
|
||||
|
||||
typedef typename
|
||||
boost::remove_cv<
|
||||
typename std::iterator_traits<I2>
|
||||
::value_type>::type v2_t;
|
||||
|
||||
enum{ can_opt =
|
||||
boost::is_same<v1_t, v2_t>::value
|
||||
&& boost::is_pointer<I1>::value
|
||||
&& boost::is_pointer<I2>::value
|
||||
&& boost::
|
||||
has_trivial_assign<v1_t>::value
|
||||
};
|
||||
|
||||
return detail::copier<can_opt>::
|
||||
do_copy(first, last, out);
|
||||
}</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><EFBFBD> Copyright John Maddock and Steve Cleary, 2000</p>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +1,5 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// (C) Copyright John Maddock and Steve Cleary 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
@ -73,3 +73,4 @@ struct ice_and<true, true, true, true, true, true, true>
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
@ -87,3 +87,4 @@ public:
|
||||
#endif // SAME_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
@ -175,6 +175,8 @@ public:
|
||||
// include a bunch of full specialisations as a workaround:
|
||||
//
|
||||
#include <boost/type_traits/transform_traits_spec.hpp>
|
||||
#else
|
||||
#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x)
|
||||
#endif
|
||||
|
||||
#endif // TRANSFORM_TRAITS_HPP
|
||||
@ -182,3 +184,4 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
#define BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
|
||||
#ifndef TRANSFORM_TRAITS_HPP
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
#endif
|
||||
@ -67,9 +70,5 @@ BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(float)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(double)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(long double)
|
||||
|
||||
#undef BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_CONST_VOLATILE_RANK1
|
||||
#undef BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1
|
||||
#undef BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_2
|
||||
#undef BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1
|
||||
#undef BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2
|
||||
#endif // BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<meta name="Template"
|
||||
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
||||
<title>Type Traits</title>
|
||||
</head>
|
||||
|
||||
@ -471,8 +471,8 @@ relationship between two types:</p>
|
||||
<p align="center">8.5</p>
|
||||
</td>
|
||||
<td valign="top" width="25%" bgcolor="#C0C0C0">Note that
|
||||
this template is currently broken with Borland's compiler,
|
||||
for constructor-based conversions.</td>
|
||||
this template is currently broken with Borland's
|
||||
compiler, for constructor-based conversions.</td>
|
||||
<td valign="top" width="5%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -595,7 +595,64 @@ transformation to the template argument T:</p>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> </p>
|
||||
<p>As the table above indicates, support for partial
|
||||
specialization of class templates is required to correctly
|
||||
implement the type transformation templates. On the other hand,
|
||||
practice shows that many of the templates from this category are
|
||||
very useful, and often essential for implementing some generic
|
||||
libraries. Lack of these templates is often one of the major
|
||||
limiting factors in porting those libraries to compilers that do
|
||||
not yet support this language feature. As some of these compilers
|
||||
are going to be around for a while, and at least one of them is
|
||||
very wide-spread, it was decided that the library should provide
|
||||
workarounds where possible. The basic idea behind the workaround
|
||||
is</p>
|
||||
|
||||
<ol>
|
||||
<li>To manually define full specializations of all type
|
||||
transformation templates for all fundamental types, and
|
||||
all their 1st and 2nd rank cv-[un]qualified derivative
|
||||
pointer types, and to</li>
|
||||
<li>Provide a user-level macro that will define such explicit
|
||||
specializations for any user-defined type T.</li>
|
||||
</ol>
|
||||
|
||||
<p>The first part guarantees the successful compilation of
|
||||
something like this:</p>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));</pre>
|
||||
|
||||
<pre>...</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));</pre>
|
||||
|
||||
<p>and the second part provides library's users with a mechanism
|
||||
to make the above code work not only for 'char', 'int' or other
|
||||
built-in type, but for they own types too:</p>
|
||||
|
||||
<pre>struct my {};</pre>
|
||||
|
||||
<pre>BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(my)</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<my, remove_reference<my&>::type>::value));</pre>
|
||||
|
||||
<pre>BOOST_STATIC_ASSERT((is_same<my, remove_const<my const>::type>::value));</pre>
|
||||
|
||||
<pre>// etc.</pre>
|
||||
|
||||
<p>Note that the maco
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to
|
||||
nothing on those compilers that do support partial specialisation.</p>
|
||||
|
||||
<h2><a name="compiler"></a>Compiler Support Information</h2>
|
||||
|
||||
@ -637,11 +694,11 @@ happen if: T is a union or T is a compiler-supplied scalar type
|
||||
that is not specialised for in these type traits.</p>
|
||||
|
||||
<p><i>If there is no compiler support</i>, to ensure that these
|
||||
traits <i>always</i> return the correct values, specialise 'is_union'
|
||||
for each user-defined union type, 'is_empty' for each user-defined
|
||||
empty composite type, and 'is_POD' for each user-defined POD type.
|
||||
The 'has_*' traits should also be specialized if the user-defined
|
||||
type has those traits and is <i>not</i> a POD.</p>
|
||||
traits <i>always</i> return the correct values, specialise
|
||||
'is_union' for each user-defined union type, 'is_empty' for each
|
||||
user-defined empty composite type, and 'is_POD' for each user-defined
|
||||
POD type. The 'has_*' traits should also be specialized if the
|
||||
user-defined type has those traits and is <i>not</i> a POD.</p>
|
||||
|
||||
<p>The following rules are automatically enforced:</p>
|
||||
|
||||
|
240
examples/copy_example.cpp
Normal file
240
examples/copy_example.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1999
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* This file provides some example of type_traits usage -
|
||||
* by "optimising" various algorithms:
|
||||
*
|
||||
* opt::copy - optimised for trivial copy (cf std::copy)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
namespace opt{
|
||||
|
||||
//
|
||||
// opt::copy
|
||||
// same semantics as std::copy
|
||||
// calls memcpy where appropiate.
|
||||
//
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename I1, typename I2>
|
||||
I2 copy_imp(I1 first, I1 last, I2 out)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*out = *first;
|
||||
++out;
|
||||
++first;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
struct copier
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2 do_copy(I1 first, I1 last, I2 out)
|
||||
{ return copy_imp(first, last, out); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct copier<true>
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2* do_copy(I1* first, I1* last, I2* out)
|
||||
{
|
||||
memcpy(out, first, (last-first)*sizeof(I2));
|
||||
return out+(last-first);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I1>::value_type>::type v1_t;
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I2>::value_type>::type v2_t;
|
||||
return detail::copier<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_same<v1_t, v2_t>::value,
|
||||
::boost::is_pointer<I1>::value,
|
||||
::boost::is_pointer<I2>::value,
|
||||
::boost::has_trivial_assign<v1_t>::value
|
||||
>::value>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
#else // BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
//
|
||||
// If there is no standard iterator_traits then we have to
|
||||
// use overloading rather than iterator_traits to detect
|
||||
// when we have T*'s to copy. Note that we cannot overload
|
||||
// copy directly as that will cause some standard conforming
|
||||
// code to fail to build:
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy_(const I1& first, const I1& last, const I2& out)
|
||||
{
|
||||
return detail::copier<false>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* copy_(const T* first, const T* last, T* out)
|
||||
{
|
||||
return detail::copier<
|
||||
::boost::has_trivial_assign<T>::value
|
||||
>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
return detail::copy_(first, last, out);
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
}; // namespace opt
|
||||
|
||||
//
|
||||
// define some global data:
|
||||
//
|
||||
const int array_size = 1000;
|
||||
int i_array_[array_size] = {0,};
|
||||
const int ci_array_[array_size] = {0,};
|
||||
char c_array_[array_size] = {0,};
|
||||
const char cc_array_[array_size] = { 0,};
|
||||
//
|
||||
// since arrays aren't iterators we define a set of pointer
|
||||
// aliases into the arrays (otherwise the compiler is entitled
|
||||
// to deduce the type passed to the template functions as
|
||||
// T (&)[N] rather than T*).
|
||||
int* i_array = i_array_;
|
||||
const int* ci_array = ci_array_;
|
||||
char* c_array = c_array_;
|
||||
const char* cc_array = cc_array_;
|
||||
|
||||
const int iter_count = 1000000;
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::timer t;
|
||||
double result;
|
||||
int i;
|
||||
cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
|
||||
cout << "testing copy...\n"
|
||||
"[Some standard library versions may already perform this optimisation.]" << endl;
|
||||
|
||||
// cache load:
|
||||
opt::copy(ci_array, ci_array + array_size, i_array);
|
||||
|
||||
// time optimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::copy(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::copy<const int*, int*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
std::copy(ci_array, ci_array + array_size, i_array);
|
||||
|
||||
// time standard version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::copy(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const int*, int*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::detail::copier<false>::do_copy(ci_array, ci_array + array_size, i_array);
|
||||
|
||||
// time unoptimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::do_copy(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
// cache load:
|
||||
opt::copy(cc_array, cc_array + array_size, c_array);
|
||||
|
||||
// time optimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::copy(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::copy<const char*, char*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
std::copy(cc_array, cc_array + array_size, c_array);
|
||||
|
||||
// time standard version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::copy(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const char*, char*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::detail::copier<false>::do_copy(cc_array, cc_array + array_size, c_array);
|
||||
|
||||
// time unoptimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::do_copy(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
191
examples/fill_example.cpp
Normal file
191
examples/fill_example.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1999
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* This file provides some example of type_traits usage -
|
||||
* by "optimising" various algorithms:
|
||||
*
|
||||
* opt::fill - optimised for trivial copy/small types (cf std::fill)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE) || (defined(std) && defined(__SGI_STL_PORT))
|
||||
namespace std{ using :: memset; }
|
||||
#endif
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
namespace opt{
|
||||
//
|
||||
// fill
|
||||
// same as std::fill, uses memset where appropriate, along with call_traits
|
||||
// to "optimise" parameter passing.
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <typename I, typename T>
|
||||
void do_fill_(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*first = val;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
template <bool opt>
|
||||
struct filler
|
||||
{
|
||||
template <typename I, typename T>
|
||||
struct rebind
|
||||
{
|
||||
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
{ do_fill_<I,T>(first, last, val); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct filler<true>
|
||||
{
|
||||
template <typename I, typename T>
|
||||
struct rebind
|
||||
{
|
||||
static void do_fill(I first, I last, T val)
|
||||
{
|
||||
std::memset(first, val, last-first);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class I, class T>
|
||||
inline void fill(I first, I last, const T& val)
|
||||
{
|
||||
typedef detail::filler<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_pointer<I>::value,
|
||||
::boost::is_arithmetic<T>::value,
|
||||
(sizeof(T) == 1)
|
||||
>::value> filler_t;
|
||||
typedef typename filler_t:: template rebind<I,T> binder;
|
||||
binder::do_fill(first, last, val);
|
||||
}
|
||||
|
||||
}; // namespace opt
|
||||
|
||||
//
|
||||
// define some global data:
|
||||
//
|
||||
const int array_size = 1000;
|
||||
int i_array_[array_size] = {0,};
|
||||
const int ci_array_[array_size] = {0,};
|
||||
char c_array_[array_size] = {0,};
|
||||
const char cc_array_[array_size] = { 0,};
|
||||
//
|
||||
// since arrays aren't iterators we define a set of pointer
|
||||
// aliases into the arrays (otherwise the compiler is entitled
|
||||
// to deduce the type passed to the template functions as
|
||||
// T (&)[N] rather than T*).
|
||||
int* i_array = i_array_;
|
||||
const int* ci_array = ci_array_;
|
||||
char* c_array = c_array_;
|
||||
const char* cc_array = cc_array_;
|
||||
|
||||
const int iter_count = 1000000;
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::timer t;
|
||||
double result;
|
||||
int i;
|
||||
//
|
||||
// test destroy_array,
|
||||
// compare destruction time of an array of ints
|
||||
// with unoptimised form.
|
||||
//
|
||||
cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
|
||||
|
||||
cout << "testing fill(char)...\n"
|
||||
"[Some standard library versions may already perform this optimisation.]" << endl;
|
||||
|
||||
// cache load:
|
||||
opt::fill(c_array, c_array + array_size, (char)3);
|
||||
|
||||
// time optimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::fill(c_array, c_array + array_size, (char)3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::fill<char*, char>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
std::fill(c_array, c_array + array_size, (char)3);
|
||||
|
||||
// time standard version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::fill(c_array, c_array + array_size, (char)3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::fill<char*, char>: " << result << endl << endl;
|
||||
|
||||
cout << "testing fill(int)...\n"
|
||||
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
|
||||
|
||||
// cache load:
|
||||
opt::fill(i_array, i_array + array_size, 3);
|
||||
|
||||
// timer optimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::fill(i_array, i_array + array_size, 3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::fill<int*, int>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
std::fill(i_array, i_array + array_size, 3);
|
||||
|
||||
// time standard version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::fill(i_array, i_array + array_size, 3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::fill<int*, int>: " << result << endl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
110
examples/iter_swap_example.cpp
Normal file
110
examples/iter_swap_example.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1999
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* This file provides some example of type_traits usage -
|
||||
* by "optimising" various algorithms:
|
||||
*
|
||||
* opt::iter_swap - uses type_traits to determine whether the iterator is a proxy
|
||||
* in which case it uses a "safe" approach, otherwise calls swap
|
||||
* on the assumption that swap may be specialised for the pointed-to type.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
namespace opt{
|
||||
|
||||
//
|
||||
// iter_swap:
|
||||
// tests whether iterator is a proxying iterator or not, and
|
||||
// uses optimal form accordingly:
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <bool b>
|
||||
struct swapper
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type v_t;
|
||||
v_t v = *one;
|
||||
*one = *two;
|
||||
*two = v;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
using std::swap;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct swapper<true>
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
using std::swap;
|
||||
swap(*one, *two);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename I1, typename I2>
|
||||
inline void iter_swap(I1 one, I2 two)
|
||||
{
|
||||
typedef typename std::iterator_traits<I1>::reference r1_t;
|
||||
typedef typename std::iterator_traits<I2>::reference r2_t;
|
||||
detail::swapper<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_reference<r1_t>::value,
|
||||
::boost::is_reference<r2_t>::value,
|
||||
::boost::is_same<r1_t, r2_t>::value
|
||||
>::value>::do_swap(one, two);
|
||||
}
|
||||
|
||||
|
||||
}; // namespace opt
|
||||
|
||||
int main()
|
||||
{
|
||||
//
|
||||
// testing iter_swap
|
||||
// really just a check that it does in fact compile...
|
||||
std::vector<int> v1;
|
||||
v1.push_back(0);
|
||||
v1.push_back(1);
|
||||
std::vector<bool> v2;
|
||||
v2.push_back(0);
|
||||
v2.push_back(1);
|
||||
opt::iter_swap(v1.begin(), v1.begin()+1);
|
||||
opt::iter_swap(v2.begin(), v2.begin()+1);
|
||||
|
||||
cout << "Press any key to exit...";
|
||||
cin.get();
|
||||
}
|
||||
|
||||
|
166
examples/trivial_destructor_example.cpp
Normal file
166
examples/trivial_destructor_example.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1999
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* This file provides some example of type_traits usage -
|
||||
* by "optimising" various algorithms:
|
||||
*
|
||||
* opt::destroy_array - an example of optimisation based upon omitted destructor calls
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
namespace opt{
|
||||
|
||||
//
|
||||
// algorithm destroy_array:
|
||||
// The reverse of std::unitialized_copy, takes a block of
|
||||
// initialized memory and calls destructors on all objects therein.
|
||||
//
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <bool>
|
||||
struct array_destroyer
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct array_destroyer<true>
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T*, T*){}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void do_destroy_array(T* first, T* last)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
first->~T();
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace detail
|
||||
|
||||
template <class T>
|
||||
inline void destroy_array(T* p1, T* p2)
|
||||
{
|
||||
detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
|
||||
}
|
||||
|
||||
//
|
||||
// unoptimised versions of destroy_array:
|
||||
//
|
||||
template <class T>
|
||||
void destroy_array1(T* first, T* last)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
first->~T();
|
||||
++first;
|
||||
}
|
||||
}
|
||||
template <class T>
|
||||
void destroy_array2(T* first, T* last)
|
||||
{
|
||||
for(; first != last; ++first) first->~T();
|
||||
}
|
||||
|
||||
} // namespace opt
|
||||
|
||||
//
|
||||
// define some global data:
|
||||
//
|
||||
const int array_size = 1000;
|
||||
int i_array[array_size] = {0,};
|
||||
const int ci_array[array_size] = {0,};
|
||||
char c_array[array_size] = {0,};
|
||||
const char cc_array[array_size] = { 0,};
|
||||
|
||||
const int iter_count = 1000000;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::timer t;
|
||||
double result;
|
||||
int i;
|
||||
//
|
||||
// test destroy_array,
|
||||
// compare destruction time of an array of ints
|
||||
// with unoptimised form.
|
||||
//
|
||||
cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
|
||||
cout << "testing destroy_array...\n"
|
||||
"[Some compilers may be able to optimise the \"unoptimised\"\n versions as well as type_traits does.]" << endl;
|
||||
|
||||
// cache load:
|
||||
opt::destroy_array(i_array, i_array + array_size);
|
||||
|
||||
// time optimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::destroy_array1(i_array, i_array + array_size);
|
||||
|
||||
// time unoptimised version #1:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array1(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>(unoptimised#1): " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::destroy_array2(i_array, i_array + array_size);
|
||||
|
||||
// time unoptimised version #2:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array2(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -10,14 +10,33 @@
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#define BOOST_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#include <boost/type_traits/alignment_traits.hpp>
|
||||
#include <boost/type_traits/object_traits.hpp>
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#include <boost/detail/ob_type_traits.hpp>
|
||||
#else
|
||||
#include <boost/detail/type_traits.hpp>
|
||||
#endif
|
||||
/**************************************************************************/
|
||||
|
||||
//
|
||||
// undefine helper macro's:
|
||||
//
|
||||
#undef BOOST_IS_CLASS
|
||||
#undef BOOST_IS_ENUM
|
||||
#undef BOOST_IS_UNION
|
||||
#undef BOOST_IS_POD
|
||||
#undef BOOST_IS_EMPTY
|
||||
#undef BOOST_HAS_TRIVIAL_CONSTRUCTOR
|
||||
#undef BOOST_HAS_TRIVIAL_COPY
|
||||
#undef BOOST_HAS_TRIVIAL_ASSIGN
|
||||
#undef BOOST_HAS_TRIVIAL_DESTRUCTOR
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
82
include/boost/type_traits/alignment_traits.hpp
Normal file
82
include/boost/type_traits/alignment_traits.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
//
|
||||
// defines alignment_of:
|
||||
|
||||
#ifndef ALIGNMENT_TYPE_TRAITS_HPP
|
||||
#define ALIGNMENT_TYPE_TRAITS_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
//
|
||||
// get the alignment of some arbitrary type:
|
||||
namespace detail{
|
||||
|
||||
template <class T>
|
||||
struct alignment_of_hack
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
alignment_of_hack();
|
||||
};
|
||||
|
||||
template <unsigned A, unsigned S>
|
||||
struct alignment_logic
|
||||
{
|
||||
BOOST_DECL_MC(std::size_t, value, A < S ? A : S);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T>
|
||||
struct alignment_of
|
||||
{
|
||||
BOOST_DECL_MC(std::size_t, value,
|
||||
(::boost::detail::alignment_logic<
|
||||
sizeof(detail::alignment_of_hack<T>) - sizeof(T),
|
||||
sizeof(T)
|
||||
>::value));
|
||||
};
|
||||
|
||||
//
|
||||
// references have to be treated specially, assume
|
||||
// that a reference is just a special pointer:
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct alignment_of<T&>
|
||||
{
|
||||
public:
|
||||
BOOST_DECL_MC(std::size_t, value, alignment_of<T*>::value);
|
||||
};
|
||||
#endif
|
||||
//
|
||||
// void has to be treated specially:
|
||||
template <>
|
||||
struct alignment_of<void>
|
||||
{ BOOST_DECL_MC(std::size_t, value, 0); };
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct alignment_of<const void>
|
||||
{ BOOST_DECL_MC(std::size_t, value, 0); };
|
||||
template <>
|
||||
struct alignment_of<volatile void>
|
||||
{ BOOST_DECL_MC(std::size_t, value, 0); };
|
||||
template <>
|
||||
struct alignment_of<const volatile void>
|
||||
{ BOOST_DECL_MC(std::size_t, value, 0); };
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // ALIGNMENT_TYPE_TRAITS_HPP
|
||||
|
||||
|
262
include/boost/type_traits/arithmetic_traits.hpp
Normal file
262
include/boost/type_traits/arithmetic_traits.hpp
Normal file
@ -0,0 +1,262 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines traits classes for arithmetic types:
|
||||
// is_void, is_integral, is_float, is_arithmetic, is_fundamental.
|
||||
//
|
||||
|
||||
|
||||
#ifndef ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#define ARITHMETIC_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
//* is a type T void - is_void<T>
|
||||
template <typename T> struct is_void{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <> struct is_void<void>{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
//* is a type T an integral type described in the standard (3.9.1p3)
|
||||
template <typename T> struct is_integral
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <> struct is_integral<unsigned char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<unsigned short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<unsigned int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<unsigned long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<signed char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<signed short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<signed int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<signed long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#ifndef BOOST_MSVC
|
||||
template <> struct is_integral<wchar_t>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
template <> struct is_integral<bool>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
|
||||
template <> struct is_integral<unsigned long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
template <> struct is_integral<unsigned __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<__int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
|
||||
//* is a type T a floating-point type described in the standard (3.9.1p8)
|
||||
template <typename T> struct is_float
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <> struct is_float<float>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<long double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
//
|
||||
// declare cv-qualified specialisations of these templates only
|
||||
// if BOOST_NO_CV_SPECIALIZATIONS is not defined:
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <> struct is_void<const void>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_void<volatile void>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_void<const volatile void>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
#ifndef BOOST_NO_CV_SPECIALIZATIONS
|
||||
// const-variations:
|
||||
template <> struct is_integral<const unsigned char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const unsigned short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const unsigned int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const unsigned long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const signed char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const signed short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const signed int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const signed long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#ifndef BOOST_MSVC
|
||||
template <> struct is_integral<const wchar_t>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
template <> struct is_integral<const bool>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
|
||||
template <> struct is_integral<const unsigned long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif // ULLONG_MAX
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
template <> struct is_integral<const unsigned __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif //__int64
|
||||
|
||||
template <> struct is_float<const float>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<const double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<const long double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
// volatile-variations:
|
||||
template <> struct is_integral<volatile unsigned char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile unsigned short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile unsigned int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile unsigned long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile signed char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile signed short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile signed int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile signed long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#ifndef BOOST_MSVC
|
||||
template <> struct is_integral<volatile wchar_t>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
template <> struct is_integral<volatile bool>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#ifdef ULLONG_MAX
|
||||
template <> struct is_integral<volatile unsigned long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif // ULLONG_MAX
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
template <> struct is_integral<volatile unsigned __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<volatile __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif //__int64
|
||||
|
||||
template <> struct is_float<volatile float>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<volatile double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<volatile long double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
// const-volatile-variations:
|
||||
template <> struct is_integral<const volatile unsigned char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile unsigned short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile unsigned int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile unsigned long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile signed char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile signed short>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile signed int>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile signed long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile char>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#ifndef BOOST_MSVC
|
||||
template <> struct is_integral<const volatile wchar_t>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
template <> struct is_integral<const volatile bool>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#ifdef ULLONG_MAX
|
||||
template <> struct is_integral<const volatile unsigned long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile long long>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif // ULLONG_MAX
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
|
||||
template <> struct is_integral<const volatile unsigned __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_integral<const volatile __int64>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif //__int64
|
||||
|
||||
template <> struct is_float<const volatile float>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<const volatile double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <> struct is_float<const volatile long double>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#endif // BOOST_NO_CV_SPECIALIZATIONS
|
||||
|
||||
//* is a type T an arithmetic type described in the standard (3.9.1p8)
|
||||
template <typename T>
|
||||
struct is_arithmetic
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_integral<T>::value,
|
||||
::boost::is_float<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
//* is a type T a fundamental type described in the standard (3.9.1)
|
||||
template <typename T>
|
||||
struct is_fundamental
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_arithmetic<T>::value,
|
||||
::boost::is_void<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
357
include/boost/type_traits/composite_traits.hpp
Normal file
357
include/boost/type_traits/composite_traits.hpp
Normal file
@ -0,0 +1,357 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines traits classes for composite types:
|
||||
// is_array, is_pointer, is_reference, is_member_pointer, is_enum, is_union.
|
||||
//
|
||||
// Some workarounds in here use ideas suggested from "Generic<Programming>:
|
||||
// Mappings between Types and Values"
|
||||
// by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
|
||||
// Mat Marcus and Jesse Jones posted a version of is_pointer very similar to this one
|
||||
// on the boost list (Copyright 2000 Adobe Systems Incorporated and others.
|
||||
// All rights reserved.).
|
||||
// Fixes for is_array are based on a newgroup posting by Jonathan Lundquist.
|
||||
|
||||
#ifndef COMPOSITE_TYPE_TRAITS_HPP
|
||||
#define COMPOSITE_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_CONVERSION_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#endif
|
||||
#ifndef CV_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#endif
|
||||
#ifndef ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_array
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T> struct is_array
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <typename T, std::size_t N> struct is_array<T[N]>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, std::size_t N> struct is_array<const T[N]>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, std::size_t N> struct is_array<volatile T[N]>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, std::size_t N> struct is_array<const volatile T[N]>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail{
|
||||
struct pointer_helper
|
||||
{
|
||||
pointer_helper(const volatile void*);
|
||||
};
|
||||
yes_type is_pointer_helper(pointer_helper);
|
||||
no_type is_pointer_helper(...);
|
||||
template <class T>
|
||||
yes_type is_pointer_helper3(T (*)(void));
|
||||
template <class T, class A1>
|
||||
yes_type is_pointer_helper3(T (*)(A1));
|
||||
template <class T, class A1, class A2>
|
||||
yes_type is_pointer_helper3(T (*)(A1, A2));
|
||||
template <class T, class A1, class A2, class A3>
|
||||
yes_type is_pointer_helper3(T (*)(A1, A2, A3));
|
||||
no_type is_pointer_helper3(...);
|
||||
|
||||
yes_type is_array_helper(const volatile void*, const volatile void*);
|
||||
template <class T>
|
||||
no_type is_array_helper(T*const volatile*, const volatile void*);
|
||||
no_type is_array_helper(...);
|
||||
} // namespace detail
|
||||
template <typename T>
|
||||
struct is_array
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, (1 == sizeof(detail::is_array_helper(&t, t)))
|
||||
& !is_reference<T>::value
|
||||
& !(1 == sizeof(detail::is_pointer_helper3(t))) );
|
||||
};
|
||||
template <>
|
||||
struct is_array<void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_array<const void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_array<volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_array<const volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_pointer
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail{
|
||||
template <typename T> struct is_pointer_helper
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <typename T> struct is_pointer_helper<T*>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T> struct is_pointer_helper<T*const>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T> struct is_pointer_helper<T*volatile>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T> struct is_pointer_helper<T*const volatile>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
} // namespace detail
|
||||
template <typename T> struct is_pointer
|
||||
{ BOOST_DECL_MC(bool, value, (::boost::type_traits::ice_and< ::boost::detail::is_pointer_helper<T>::value, !::boost::is_member_pointer<T>::value>::value)); };
|
||||
#else
|
||||
template <typename T>
|
||||
struct is_pointer
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
!::boost::is_reference<T>::value,
|
||||
!::boost::is_array<T>::value,
|
||||
(::boost::type_traits::ice_or<
|
||||
(1 == sizeof(detail::is_pointer_helper(t))),
|
||||
(1 == sizeof(detail::is_pointer_helper3(t)))
|
||||
>::value)
|
||||
>::value ) );
|
||||
};
|
||||
template <>
|
||||
struct is_pointer <void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_pointer <const void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_pointer <volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_pointer <const volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_reference
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T> struct is_reference
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <typename T> struct is_reference<T&>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#if defined(__BORLANDC__)
|
||||
// these are illegal specialisations; cv-qualifies applied to
|
||||
// references have no effect according to [8.3.2p1],
|
||||
// C++ Builder requires them though as it treats cv-qualified
|
||||
// references as distinct types...
|
||||
template <typename T> struct is_reference<T&const>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T> struct is_reference<T&volatile>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T> struct is_reference<T&const volatile>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
#else
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4181)
|
||||
# endif // BOOST_MSVC
|
||||
template <typename T> struct is_reference
|
||||
{
|
||||
private:
|
||||
typedef T const volatile cv_t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, (::boost::type_traits::ice_or<!::boost::is_const<cv_t>::value, !::boost::is_volatile<cv_t>::value>::value));
|
||||
};
|
||||
template <> struct is_reference<void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <> struct is_reference<const void>
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <> struct is_reference<volatile void>
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <> struct is_reference<const volatile void>
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
#endif
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
# endif // BOOST_MSVC
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_union
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T> struct is_union
|
||||
{
|
||||
private:
|
||||
typedef typename remove_cv<T>::type cvt;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, BOOST_IS_UNION(cvt));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_enum
|
||||
*
|
||||
**********************************************/
|
||||
namespace detail{
|
||||
struct int_convertible
|
||||
{
|
||||
int_convertible(int);
|
||||
};
|
||||
} // namespace detail
|
||||
#ifndef __BORLANDC__
|
||||
template <typename T> struct is_enum
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
!::boost::is_arithmetic<T>::value,
|
||||
!::boost::is_reference<T>::value,
|
||||
::boost::is_convertible<T, detail::int_convertible>::value
|
||||
>::value));
|
||||
};
|
||||
#else // __BORLANDC__
|
||||
//
|
||||
// buggy is_convertible prevents working
|
||||
// implementation of is_enum:
|
||||
template <typename T> struct is_enum
|
||||
{
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, BOOST_IS_ENUM(T));
|
||||
};
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_member_pointer
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T> struct is_member_pointer
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
template <typename T, typename U> struct is_member_pointer<U T::*>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#ifdef __GNUC__
|
||||
// gcc workaround (JM 02 Oct 2000)
|
||||
template <typename T, typename U> struct is_member_pointer<U (T::*)(void)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, typename U, typename A1> struct is_member_pointer<U (T::*)(A1)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, typename U, typename A1, typename A2> struct is_member_pointer<U (T::*)(A1, A2)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, typename U, typename A1, typename A2, typename A3> struct is_member_pointer<U (T::*)(A1, A2, A3)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, typename U, typename A1, typename A2, typename A3, typename A4> struct is_member_pointer<U (T::*)(A1, A2, A3, A4)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <typename T, typename U, typename A1, typename A2, typename A3, typename A4, typename A5> struct is_member_pointer<U (T::*)(A1, A2, A3, A4, A5)>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
#endif
|
||||
#else
|
||||
namespace detail{
|
||||
template <class T, class U>
|
||||
yes_type is_member_pointer_helper(T (U::*));
|
||||
template <class T, class U>
|
||||
yes_type is_member_pointer_helper(T (U::*)(void));
|
||||
template <class T, class U, class A1>
|
||||
yes_type is_member_pointer_helper(T (U::*)(A1));
|
||||
template <class T, class U, class A1, class A2>
|
||||
yes_type is_member_pointer_helper(T (U::*)(A1, A2));
|
||||
template <class T, class U, class A1, class A2, class A3>
|
||||
yes_type is_member_pointer_helper(T (U::*)(A1, A2, A3));
|
||||
template <class T, class U, class A1, class A2, class A3, class A4>
|
||||
yes_type is_member_pointer_helper(T (U::*)(A1, A2, A3, A4));
|
||||
template <class T, class U, class A1, class A2, class A3, class A4, class A5>
|
||||
yes_type is_member_pointer_helper(T (U::*)(A1, A2, A3, A4, A5));
|
||||
no_type is_member_pointer_helper(...);
|
||||
}
|
||||
template <typename T>
|
||||
struct is_member_pointer
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, (1 == sizeof(detail::is_member_pointer_helper(t))) );
|
||||
};
|
||||
template <>
|
||||
struct is_member_pointer<void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_member_pointer<const void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_member_pointer<volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_member_pointer<const volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // COMPOSITE_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
224
include/boost/type_traits/conversion_traits.hpp
Normal file
224
include/boost/type_traits/conversion_traits.hpp
Normal file
@ -0,0 +1,224 @@
|
||||
|
||||
// Copyright (C) 2000 John Maddock (john_maddock@compuserve.com)
|
||||
// Copyright (C) 2000 Jeremy Siek (jsiek@lsc.nd.edu)
|
||||
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
|
||||
//
|
||||
// Permission to copy and use this software is granted,
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted,
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_CONVERSION_TYPE_TRAITS_HPP
|
||||
#define BOOST_CONVERSION_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
#ifndef ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#endif
|
||||
//
|
||||
// is one type convertable to another?
|
||||
//
|
||||
// there are multiple versions of the is_convertible
|
||||
// template, almost every compiler seems to require its
|
||||
// own version.
|
||||
//
|
||||
// Thanks to Andrei Alexandrescu for the original version of the
|
||||
// conversion detection technique!
|
||||
//
|
||||
|
||||
namespace boost{
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
||||
//
|
||||
// MS specific version:
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
// This workaround is necessary to handle when From is void
|
||||
// which is normally taken care of by the partial specialization
|
||||
// of the is_convertible class.
|
||||
using ::boost::type_traits::yes_type;
|
||||
using ::boost::type_traits::no_type;
|
||||
|
||||
struct from_not_void_conversion {
|
||||
template <class From, class To>
|
||||
struct bind {
|
||||
static no_type check(...);
|
||||
static yes_type check(To);
|
||||
public:
|
||||
void foo(); // avoid warning about all members being private
|
||||
static From from;
|
||||
enum { exists = sizeof( check(from) ) == sizeof(yes_type) };
|
||||
};
|
||||
};
|
||||
struct from_is_void_conversion {
|
||||
template <class From, class To>
|
||||
struct bind {
|
||||
enum { exists = ::boost::is_void<To>::value };
|
||||
};
|
||||
};
|
||||
|
||||
template <class From>
|
||||
struct conversion_helper {
|
||||
typedef from_not_void_conversion type;
|
||||
};
|
||||
template <>
|
||||
struct conversion_helper<void> {
|
||||
typedef from_is_void_conversion type;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <class From, class To>
|
||||
struct is_convertible
|
||||
{
|
||||
typedef typename detail::conversion_helper<From>::type Selector;
|
||||
typedef Selector::template bind<From,To> Conversion;
|
||||
public:
|
||||
enum { value = Conversion::exists };
|
||||
};
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
//
|
||||
// special version for Borland compilers
|
||||
// this version breaks when used for some
|
||||
// UDT conversions:
|
||||
//
|
||||
template <class From, class To>
|
||||
struct is_convertible_helper
|
||||
{
|
||||
private:
|
||||
// This workaround for Borland breaks the EDG C++ frontend,
|
||||
// so we only use it for Borland.
|
||||
template <class T>
|
||||
struct checker
|
||||
{
|
||||
static type_traits::no_type check(...);
|
||||
static type_traits::yes_type check(T);
|
||||
};
|
||||
static From from;
|
||||
public:
|
||||
static const bool value = sizeof( checker<To>::check(from) ) == sizeof(type_traits::yes_type);
|
||||
|
||||
void foo(); // avoid warning about all members being private
|
||||
};
|
||||
|
||||
template <class From, class To>
|
||||
struct is_convertible
|
||||
{
|
||||
private:
|
||||
typedef is_convertible_helper<From, To> c_type;
|
||||
enum{ v = c_type::value };
|
||||
char force_it[v ? 1 : 2];
|
||||
public:
|
||||
static const bool value = is_convertible_helper<From, To>::value;
|
||||
};
|
||||
|
||||
template <class From>
|
||||
struct is_convertible<From, void>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
template <class To>
|
||||
struct is_convertible<void, To>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
template <>
|
||||
struct is_convertible<void, void>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
//
|
||||
// special version for gcc compiler
|
||||
//
|
||||
namespace detail{
|
||||
struct any_conversion
|
||||
{
|
||||
template <class T>
|
||||
any_conversion(const T&);
|
||||
};
|
||||
template <class T>
|
||||
struct checker
|
||||
{
|
||||
static boost::type_traits::no_type check(any_conversion ...);
|
||||
static boost::type_traits::yes_type check(T, int);
|
||||
};
|
||||
} // namespace detail
|
||||
template <class From, class To>
|
||||
struct is_convertible
|
||||
{
|
||||
private:
|
||||
static From from;
|
||||
public:
|
||||
static const bool value = sizeof( detail::checker<To>::check(from, 0) ) == sizeof(type_traits::yes_type);
|
||||
|
||||
void foo(); // avoid warning about all members being private
|
||||
};
|
||||
|
||||
template <class From>
|
||||
struct is_convertible<From, void>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
template <class To>
|
||||
struct is_convertible<void, To>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
template <>
|
||||
struct is_convertible<void, void>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <class From, class To>
|
||||
struct is_convertible
|
||||
{
|
||||
private:
|
||||
static type_traits::no_type check(...);
|
||||
static type_traits::yes_type check(To);
|
||||
static From from;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, sizeof( check(from) ) == sizeof(type_traits::yes_type));
|
||||
void foo(); // avoid warning about all members being private
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class From>
|
||||
struct is_convertible<From, void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
|
||||
template <class To>
|
||||
struct is_convertible<void, To>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_convertible<void, void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#endif // is_convertible
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // include guard
|
214
include/boost/type_traits/cv_traits.hpp
Normal file
214
include/boost/type_traits/cv_traits.hpp
Normal file
@ -0,0 +1,214 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines traits classes for cv-qualified types:
|
||||
// is_const, is_volatile, remove_const, remove_volatile, remove_cv.
|
||||
//
|
||||
|
||||
#ifndef CV_TYPE_TRAITS_HPP
|
||||
#define CV_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail{
|
||||
//
|
||||
// implementation helper:
|
||||
//
|
||||
template <class T>
|
||||
struct cv_traits_imp{};
|
||||
|
||||
template <class T>
|
||||
struct cv_traits_imp<T*>
|
||||
{
|
||||
BOOST_DECL_MC(bool, is_const, false);
|
||||
BOOST_DECL_MC(bool, is_volatile, false);
|
||||
typedef T unqualified_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct cv_traits_imp<const T*>
|
||||
{
|
||||
BOOST_DECL_MC(bool, is_const, true);
|
||||
BOOST_DECL_MC(bool, is_volatile, false);
|
||||
typedef T unqualified_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct cv_traits_imp<volatile T*>
|
||||
{
|
||||
BOOST_DECL_MC(bool, is_const, false);
|
||||
BOOST_DECL_MC(bool, is_volatile, true);
|
||||
typedef T unqualified_type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct cv_traits_imp<const volatile T*>
|
||||
{
|
||||
BOOST_DECL_MC(bool, is_const, true);
|
||||
BOOST_DECL_MC(bool, is_volatile, true);
|
||||
typedef T unqualified_type;
|
||||
};
|
||||
|
||||
template <class T, bool is_vol>
|
||||
struct remove_const_helper
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <class T>
|
||||
struct remove_const_helper<T, true>
|
||||
{
|
||||
typedef volatile T type;
|
||||
};
|
||||
|
||||
template <class T, bool is_vol>
|
||||
struct remove_volatile_helper
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
template <class T>
|
||||
struct remove_volatile_helper<T, true>
|
||||
{
|
||||
typedef const T type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// * convert a type T to a non-volatile type - remove_volatile<T>
|
||||
template <typename T>
|
||||
struct remove_volatile
|
||||
{
|
||||
typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
|
||||
typedef typename detail::remove_volatile_helper<uq_type, ::boost::is_const<T>::value>::type type;
|
||||
};
|
||||
template <typename T> struct remove_volatile<T&>{ typedef T& type; };
|
||||
|
||||
// * convert a type T to non-const type - remove_const<T>
|
||||
template <typename T>
|
||||
struct remove_const
|
||||
{
|
||||
typedef typename detail::cv_traits_imp<T*>::unqualified_type uq_type;
|
||||
typedef typename detail::remove_const_helper<uq_type, ::boost::is_volatile<T>::value>::type type;
|
||||
};
|
||||
template <typename T> struct remove_const<T&>{ typedef T& type; };
|
||||
|
||||
// convert a type T to a non-cv-qualified type - remove_cv<T>
|
||||
template <typename T>
|
||||
struct remove_cv
|
||||
{
|
||||
typedef typename detail::cv_traits_imp<T*>::unqualified_type type;
|
||||
};
|
||||
template <typename T> struct remove_cv<T&>{ typedef T& type; };
|
||||
|
||||
//* is a type T declared const - is_const<T>
|
||||
template <typename T>
|
||||
struct is_const
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, detail::cv_traits_imp<T*>::is_const);
|
||||
};
|
||||
|
||||
//* is a type T declared volatile - is_volatile<T>
|
||||
template <typename T>
|
||||
struct is_volatile
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, detail::cv_traits_imp<T*>::is_volatile);
|
||||
};
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// The following three don't work:
|
||||
template <typename T> struct remove_volatile{ typedef T type; };
|
||||
template <typename T> struct remove_const{ typedef T type; };
|
||||
template <typename T> struct remove_cv{ typedef T type; };
|
||||
|
||||
namespace detail{
|
||||
using ::boost::type_traits::yes_type;
|
||||
using ::boost::type_traits::no_type;
|
||||
yes_type is_const_helper(const volatile void*);
|
||||
no_type is_const_helper(volatile void *);
|
||||
yes_type is_volatile_helper(const volatile void*);
|
||||
no_type is_volatile_helper(const void *);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_const
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, (sizeof(detail::yes_type) == sizeof(detail::is_const_helper(&t))));
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_const<void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_const<const void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
template <>
|
||||
struct is_const<volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_const<const volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct is_volatile
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value, (sizeof(detail::yes_type) == sizeof(detail::is_volatile_helper(&t))));
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_volatile<void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_volatile<const void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct is_volatile<volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
template <>
|
||||
struct is_volatile<const volatile void>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // CV_TYPE_TRAITS_HPP
|
||||
|
||||
|
140
include/boost/type_traits/fwd.hpp
Normal file
140
include/boost/type_traits/fwd.hpp
Normal file
@ -0,0 +1,140 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// forward declarations of type_traits classes
|
||||
//
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#define BOOST_FWD_TYPE_TRAITS_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Helper macros for builtin compiler support.
|
||||
// If your compiler has builtin support for any of the following
|
||||
// traits concepts, then redefine the appropriate macros to pick
|
||||
// up on the compiler support:
|
||||
//
|
||||
// (these should largely ignore cv-qualifiers)
|
||||
// BOOST_IS_CLASS(T) should evaluate to true if T is a class or struct type
|
||||
// BOOST_IS_ENUM(T) should evaluate to true if T is an enumerator type
|
||||
// BOOST_IS_UNION(T) should evaluate to true if T is a union type
|
||||
// BOOST_IS_POD(T) should evaluate to true if T is a POD type
|
||||
// BOOST_IS_EMPTY(T) should evaluate to true if T is an empty struct or union
|
||||
// BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
|
||||
// BOOST_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
|
||||
// BOOST_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
|
||||
// BOOST_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
|
||||
|
||||
#define BOOST_IS_CLASS(T) false
|
||||
#define BOOST_IS_ENUM(T) false
|
||||
#define BOOST_IS_UNION(T) false
|
||||
#define BOOST_IS_POD(T) false
|
||||
#define BOOST_IS_EMPTY(T) false
|
||||
#define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) false
|
||||
#define BOOST_HAS_TRIVIAL_COPY(T) false
|
||||
#define BOOST_HAS_TRIVIAL_ASSIGN(T) false
|
||||
#define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) false
|
||||
|
||||
|
||||
namespace boost{
|
||||
//
|
||||
// forward declare all type traits templates here
|
||||
//
|
||||
// conversion_traits.hpp:
|
||||
template <class From, class To>
|
||||
struct is_convertible;
|
||||
// alignment_traits.hpp:
|
||||
template <class T>
|
||||
struct alignment_of;
|
||||
// arithmetic_traits.hpp:
|
||||
template <class T>
|
||||
struct is_void;
|
||||
template <class T>
|
||||
struct is_integral;
|
||||
template <class T>
|
||||
struct is_float;
|
||||
template <class T>
|
||||
struct is_arithmetic;
|
||||
template <class T>
|
||||
struct is_fundamental;
|
||||
|
||||
// cv_traits.hpp:
|
||||
template <class T>
|
||||
struct is_const;
|
||||
template <class T>
|
||||
struct is_volatile;
|
||||
template <class T>
|
||||
struct remove_const;
|
||||
template <class T>
|
||||
struct remove_volatile;
|
||||
template <class T>
|
||||
struct remove_cv;
|
||||
|
||||
// composite_traits.hpp:
|
||||
template <class T>
|
||||
struct is_array;
|
||||
template <class T>
|
||||
struct is_pointer;
|
||||
template <class T>
|
||||
struct is_reference;
|
||||
template <class T>
|
||||
struct is_member_pointer;
|
||||
template <class T>
|
||||
struct is_enum;
|
||||
template <class T>
|
||||
struct is_union;
|
||||
|
||||
// object_traits.hpp:
|
||||
template <class T>
|
||||
struct is_object;
|
||||
template <class T>
|
||||
struct is_scalar;
|
||||
template <class T>
|
||||
struct is_class;
|
||||
template <class T>
|
||||
struct is_compound;
|
||||
template <class T>
|
||||
struct is_POD;
|
||||
template <class T>
|
||||
struct has_trivial_constructor;
|
||||
template <class T>
|
||||
struct has_trivial_copy;
|
||||
template <class T>
|
||||
struct has_trivial_assign;
|
||||
template <class T>
|
||||
struct has_trivial_destructor;
|
||||
template <class T>
|
||||
struct is_empty;
|
||||
|
||||
// transform_traits.hpp:
|
||||
template <class T>
|
||||
struct remove_reference;
|
||||
template <class T>
|
||||
struct add_reference;
|
||||
template <class T>
|
||||
struct remove_bounds;
|
||||
template <class T>
|
||||
struct remove_pointer;
|
||||
template <class T>
|
||||
struct add_pointer;
|
||||
|
||||
// same_traits.hpp:
|
||||
template <class T, class U>
|
||||
struct is_same;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_FWD_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
76
include/boost/type_traits/ice.hpp
Normal file
76
include/boost/type_traits/ice.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
// (C) Copyright John Maddock and Steve Cleary 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// macros and helpers for working with integral-constant-expressions.
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#define BOOST_ICE_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
#define BOOST_DECL_MC(type, name, value) enum{name = value }
|
||||
#define BOOST_DECL_MC2(type, name, v1, v2) enum{name = v1,v2 }
|
||||
#else
|
||||
#define BOOST_DECL_MC(type, name, value) static const type name = value
|
||||
#define BOOST_DECL_MC2(type, name, v1, v2) static const type name = v1,v2
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost{
|
||||
namespace type_traits{
|
||||
|
||||
typedef char yes_type;
|
||||
typedef double no_type;
|
||||
|
||||
template <bool b>
|
||||
struct ice_not
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
template <>
|
||||
struct ice_not<true>
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
|
||||
template <bool b1, bool b2, bool b3 = false, bool b4 = false, bool b5 = false, bool b6 = false, bool b7 = false>
|
||||
struct ice_or;
|
||||
template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
|
||||
struct ice_or
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
template <>
|
||||
struct ice_or<false, false, false, false, false, false, false>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
|
||||
template <bool b1, bool b2, bool b3 = true, bool b4 = true, bool b5 = true, bool b6 = true, bool b7 = true>
|
||||
struct ice_and;
|
||||
template <bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7>
|
||||
struct ice_and
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, false);
|
||||
};
|
||||
template <>
|
||||
struct ice_and<true, true, true, true, true, true, true>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, true);
|
||||
};
|
||||
|
||||
|
||||
} // namespace type_traits
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ICE_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
318
include/boost/type_traits/object_traits.hpp
Normal file
318
include/boost/type_traits/object_traits.hpp
Normal file
@ -0,0 +1,318 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines object traits classes:
|
||||
// is_object, is_scalar, is_class, is_compound, is_POD,
|
||||
// has_trivial_constructor, has_trivial_copy, has_trivial_assign,
|
||||
// has_trivial_destructor, is_empty.
|
||||
//
|
||||
|
||||
#ifndef OBJECT_TYPE_TRAITS_HPP
|
||||
#define OBJECT_TYPE_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
#ifndef COMPOSITE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#endif
|
||||
#ifndef ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_object
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct is_object
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
!::boost::is_reference<T>::value,
|
||||
!::boost::is_void<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_scalar
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct is_scalar
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_arithmetic<T>::value,
|
||||
::boost::is_enum<T>::value,
|
||||
::boost::is_pointer<T>::value,
|
||||
::boost::is_member_pointer<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_class
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct is_class
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
!::boost::is_union<T>::value,
|
||||
!::boost::is_scalar<T>::value,
|
||||
!::boost::is_array<T>::value,
|
||||
!::boost::is_reference<T>::value,
|
||||
!::boost::is_void<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_compound
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T> struct is_compound
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_array<T>::value,
|
||||
::boost::is_pointer<T>::value,
|
||||
::boost::is_reference<T>::value,
|
||||
::boost::is_class<T>::value,
|
||||
::boost::is_union<T>::value,
|
||||
::boost::is_enum<T>::value,
|
||||
::boost::is_member_pointer<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_POD
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T> struct is_POD
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_scalar<T>::value,
|
||||
::boost::is_void<T>::value,
|
||||
BOOST_IS_POD(T)
|
||||
>::value));
|
||||
};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T, std::size_t sz>
|
||||
struct is_POD<T[sz]>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value, ::boost::is_POD<T>::value);
|
||||
};
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* has_trivial_constructor
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct has_trivial_constructor
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_POD<T>::value,
|
||||
BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* has_trivial_copy
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct has_trivial_copy
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
::boost::type_traits::ice_or<
|
||||
::boost::is_POD<T>::value,
|
||||
BOOST_HAS_TRIVIAL_COPY(T)
|
||||
>::value,
|
||||
!::boost::is_volatile<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* has_trivial_assign
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct has_trivial_assign
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
::boost::type_traits::ice_or<
|
||||
::boost::is_POD<T>::value,
|
||||
BOOST_HAS_TRIVIAL_ASSIGN(T)
|
||||
>::value,
|
||||
!::boost::is_const<T>::value,
|
||||
!::boost::is_volatile<T>::value
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* has_trivial_destructor
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct has_trivial_destructor
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::is_POD<T>::value,
|
||||
BOOST_HAS_TRIVIAL_DESTRUCTOR(T)
|
||||
>::value));
|
||||
};
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_empty
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace detail{
|
||||
|
||||
template <typename T>
|
||||
struct empty_helper_t1 : public T
|
||||
{
|
||||
#ifdef __MWERKS__
|
||||
empty_helper_t1(); // hh compiler bug workaround
|
||||
#endif
|
||||
int i[256];
|
||||
};
|
||||
struct empty_helper_t2 { int i[256]; };
|
||||
|
||||
template <typename T, bool b, bool b2>
|
||||
struct empty_helper{ BOOST_DECL_MC(bool, value, false); };
|
||||
|
||||
template <typename T>
|
||||
struct empty_helper<T, true, false>
|
||||
{
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)));
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_empty
|
||||
{
|
||||
private:
|
||||
typedef typename remove_cv<T>::type cvt;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<
|
||||
::boost::detail::empty_helper<T,
|
||||
::boost::is_class<T>::value ,
|
||||
::boost::is_convertible<T,int>::value
|
||||
>::value,
|
||||
BOOST_IS_EMPTY(cvt)
|
||||
>::value));
|
||||
};
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <typename T>
|
||||
struct empty_helper_t1 : public T
|
||||
{
|
||||
int i[256];
|
||||
};
|
||||
struct empty_helper_t2 { int i[256]; };
|
||||
|
||||
template <typename T>
|
||||
struct empty_helper_base
|
||||
{
|
||||
enum{ value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)) };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct empty_helper_nonbase
|
||||
{
|
||||
enum{ value = false };
|
||||
};
|
||||
|
||||
template <bool base>
|
||||
struct empty_helper_chooser
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef empty_helper_nonbase<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct empty_helper_chooser<true>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef empty_helper_base<T> type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct is_empty
|
||||
{
|
||||
private:
|
||||
typedef ::boost::detail::empty_helper_chooser<
|
||||
::boost::type_traits::ice_and<
|
||||
!::boost::is_convertible<T,int>::value,
|
||||
!::boost::is_convertible<T,double>::value,
|
||||
!::boost::is_pointer<T>::value,
|
||||
!::boost::is_member_pointer<T>::value,
|
||||
!::boost::is_array<T>::value,
|
||||
!::boost::is_void<T>::value,
|
||||
!::boost::is_convertible<T, const volatile void*>::value
|
||||
>::value> chooser;
|
||||
typedef typename chooser::template rebind<T> bound_type;
|
||||
typedef typename bound_type::type eh_type;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_or<eh_type::value, BOOST_IS_EMPTY(T)>::value));
|
||||
};
|
||||
|
||||
#else
|
||||
template <typename T> struct is_empty
|
||||
{ enum{ value = BOOST_IS_EMPTY(T) }; };
|
||||
#endif // defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // OBJECT_TYPE_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
90
include/boost/type_traits/same_traits.hpp
Normal file
90
include/boost/type_traits/same_traits.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines is_same:
|
||||
|
||||
#ifndef SAME_TRAITS_HPP
|
||||
#define SAME_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
#if !defined(COMPOSITE_TYPE_TRAITS_HPP) && defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC)
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* is_same
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same
|
||||
{ BOOST_DECL_MC(bool, value, false); };
|
||||
|
||||
template <typename T>
|
||||
struct is_same<T, T>
|
||||
{ BOOST_DECL_MC(bool, value, true); };
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<class T1>
|
||||
struct is_same_part_1 {
|
||||
template<class T2> struct part_2 { enum { value = false }; };
|
||||
template<> struct part_2<T1> { enum { value = true }; };
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T1, class T2>
|
||||
struct is_same : detail::is_same_part_1<T1>::template part_2<T2> {};
|
||||
|
||||
#else // BOOST_MSVC
|
||||
|
||||
namespace detail{
|
||||
template <class T>
|
||||
::boost::type_traits::yes_type is_same_helper(T*, T*);
|
||||
::boost::type_traits::no_type is_same_helper(...);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_same
|
||||
{
|
||||
private:
|
||||
static T t;
|
||||
static U u;
|
||||
public:
|
||||
BOOST_DECL_MC(bool, value,
|
||||
(::boost::type_traits::ice_and<
|
||||
(sizeof(type_traits::yes_type) == sizeof(detail::is_same_helper(&t,&u))),
|
||||
(::boost::is_reference<T>::value == ::boost::is_reference<U>::value),
|
||||
(sizeof(T) == sizeof(U))
|
||||
>::value));
|
||||
};
|
||||
|
||||
#endif // BOOST_MSVC
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // SAME_TRAITS_HPP
|
||||
|
||||
|
||||
|
187
include/boost/type_traits/transform_traits.hpp
Normal file
187
include/boost/type_traits/transform_traits.hpp
Normal file
@ -0,0 +1,187 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// defines traits classes for transforming one type to another:
|
||||
// remove_reference, add_reference, remove_bounds, remove_pointer.
|
||||
//
|
||||
|
||||
#ifndef TRANSFORM_TRAITS_HPP
|
||||
#define TRANSFORM_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_ICE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_FWD_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/fwd.hpp>
|
||||
#endif
|
||||
#if !defined(COMPOSITE_TYPE_TRAITS_HPP) && defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* remove_reference
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct remove_reference
|
||||
{ typedef T type; };
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T>
|
||||
struct remove_reference<T&>
|
||||
{ typedef T type; };
|
||||
#endif
|
||||
#if defined(__BORLANDC__) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
// these are illegal specialisations; cv-qualifies applied to
|
||||
// references have no effect according to [8.3.2p1],
|
||||
// C++ Builder requires them though as it treats cv-qualified
|
||||
// references as distinct types...
|
||||
template <typename T>
|
||||
struct remove_reference<T&const>
|
||||
{ typedef T type; };
|
||||
template <typename T>
|
||||
struct remove_reference<T&volatile>
|
||||
{ typedef T type; };
|
||||
template <typename T>
|
||||
struct remove_reference<T&const volatile>
|
||||
{ typedef T type; };
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* add_reference
|
||||
*
|
||||
**********************************************/
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T>
|
||||
struct add_reference
|
||||
{ typedef T& type; };
|
||||
template <typename T>
|
||||
struct add_reference<T&>
|
||||
{ typedef T& type; };
|
||||
#elif defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
namespace detail{
|
||||
|
||||
template <bool>
|
||||
struct reference_adder
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef T& type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct reference_adder<true>
|
||||
{
|
||||
template <class T>
|
||||
struct rebind
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct add_reference
|
||||
{
|
||||
private:
|
||||
typedef typename detail::reference_adder< ::boost::is_reference<T>::value>::template rebind<T> binder;
|
||||
public:
|
||||
typedef typename binder::type type;
|
||||
};
|
||||
|
||||
#else
|
||||
template <typename T>
|
||||
struct add_reference
|
||||
{ typedef T& type; };
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* remove_bounds
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct remove_bounds
|
||||
{ typedef T type; };
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T, std::size_t N>
|
||||
struct remove_bounds<T[N]>
|
||||
{ typedef T type; };
|
||||
template <typename T, std::size_t N>
|
||||
struct remove_bounds<const T[N]>
|
||||
{ typedef const T type; };
|
||||
template <typename T, std::size_t N>
|
||||
struct remove_bounds<volatile T[N]>
|
||||
{ typedef volatile T type; };
|
||||
template <typename T, std::size_t N>
|
||||
struct remove_bounds<const volatile T[N]>
|
||||
{ typedef const volatile T type; };
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* remove_pointer
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct remove_pointer
|
||||
{ typedef T type; };
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T>
|
||||
struct remove_pointer<T*>
|
||||
{ typedef T type; };
|
||||
template <typename T>
|
||||
struct remove_pointer<T*const>
|
||||
{ typedef T type; };
|
||||
template <typename T>
|
||||
struct remove_pointer<T*volatile>
|
||||
{ typedef T type; };
|
||||
template <typename T>
|
||||
struct remove_pointer<T*const volatile>
|
||||
{ typedef T type; };
|
||||
#endif
|
||||
|
||||
/**********************************************
|
||||
*
|
||||
* add_pointer
|
||||
*
|
||||
**********************************************/
|
||||
template <typename T>
|
||||
struct add_pointer
|
||||
{
|
||||
private:
|
||||
typedef typename remove_reference<T>::type no_ref_type;
|
||||
typedef typename remove_bounds<no_ref_type>::type no_b_type;
|
||||
public:
|
||||
typedef no_b_type* type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
//
|
||||
// if there is no partial specialisation support
|
||||
// include a bunch of full specialisations as a workaround:
|
||||
//
|
||||
#include <boost/type_traits/transform_traits_spec.hpp>
|
||||
#else
|
||||
#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x)
|
||||
#endif
|
||||
|
||||
#endif // TRANSFORM_TRAITS_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
74
include/boost/type_traits/transform_traits_spec.hpp
Normal file
74
include/boost/type_traits/transform_traits_spec.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
// Copyright (c) 2001 Aleksey Gurtovoy.
|
||||
// Permission to copy, use, modify, sell and distribute this software is
|
||||
// granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
#ifndef BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
#define BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
|
||||
#ifndef TRANSFORM_TRAITS_HPP
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
#endif
|
||||
|
||||
#define BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_CONST_VOLATILE_RANK1(T) \
|
||||
template<> struct remove_const<T const> { typedef T type; }; \
|
||||
template<> struct remove_const<T const volatile> { typedef T volatile type; }; \
|
||||
template<> struct remove_volatile<T volatile> { typedef T type; }; \
|
||||
template<> struct remove_volatile<T const volatile> { typedef T const type; }; \
|
||||
template<> struct remove_cv<T const> { typedef T type; }; \
|
||||
template<> struct remove_cv<T volatile> { typedef T type; }; \
|
||||
template<> struct remove_cv<T const volatile> { typedef T type; }; \
|
||||
/**/
|
||||
|
||||
#define BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1(T) \
|
||||
template<> struct remove_pointer<T*> { typedef T type; }; \
|
||||
template<> struct remove_reference<T&> { typedef T type; }; \
|
||||
/**/
|
||||
|
||||
#define BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_2(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1(T const) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1(T volatile) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_1(T const volatile) \
|
||||
/**/
|
||||
|
||||
#define BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_PTR_REF_RANK_2(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_CONST_VOLATILE_RANK1(T) \
|
||||
/**/
|
||||
|
||||
#define BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T const*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T volatile*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T const volatile*) \
|
||||
/**/
|
||||
|
||||
#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(T) \
|
||||
namespace boost { \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_1(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T const*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T volatile*) \
|
||||
BOOST_TYPE_TRAITS_SPECIALIZATION_REMOVE_ALL_RANK_2(T const volatile*) \
|
||||
} \
|
||||
/**/
|
||||
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(char)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(signed char)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(unsigned char)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(signed short)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(unsigned short)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(signed int)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(unsigned int)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(signed long)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(unsigned long)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(float)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(double)
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(long double)
|
||||
|
||||
#endif // BOOST_TT_TRANSFORM_TRAITS_SPEC_HPP
|
||||
|
361
include/boost/type_traits/type_traits_test.hpp
Normal file
361
include/boost/type_traits/type_traits_test.hpp
Normal file
@ -0,0 +1,361 @@
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// common test code for type-traits tests
|
||||
// WARNING: contains code as well as declarations!
|
||||
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_TEST_HPP
|
||||
#define BOOST_TYPE_TRAITS_TEST_HPP
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
//
|
||||
// define tests here
|
||||
unsigned failures = 0;
|
||||
unsigned test_count = 0;
|
||||
//
|
||||
// This must get defined within the test file.
|
||||
// All compilers have bugs, set this to the number of
|
||||
// regressions *expected* from a given compiler,
|
||||
// if there are no workarounds for the bugs, *and*
|
||||
// the regressions have been investigated.
|
||||
//
|
||||
extern unsigned int expected_failures;
|
||||
//
|
||||
// proc check_result()
|
||||
// Checks that there were no regressions:
|
||||
//
|
||||
int check_result(int argc, char** argv)
|
||||
{
|
||||
std::cout << test_count << " tests completed, "
|
||||
<< failures << " failures found, "
|
||||
<< expected_failures << " failures expected from this compiler." << std::endl;
|
||||
if((argc == 2)
|
||||
&& (argv[1][0] == '-')
|
||||
&& (argv[1][1] == 'a')
|
||||
&& (argv[1][2] == 0))
|
||||
{
|
||||
std::cout << "Press any key to continue...";
|
||||
std::cin.get();
|
||||
}
|
||||
return (failures == expected_failures) ? 0 : failures;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// this one is to verify that a constant is indeed a
|
||||
// constant-integral-expression:
|
||||
//
|
||||
template <bool>
|
||||
struct checker
|
||||
{
|
||||
static void check(bool, bool, const char*, bool){ ++test_count; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct checker<false>
|
||||
{
|
||||
static void check(bool o, bool n, const char* name, bool soft)
|
||||
{
|
||||
++test_count;
|
||||
++failures;
|
||||
// if this is a soft test, then failure is expected,
|
||||
// or may depend upon factors outside our control
|
||||
// (like compiler options)...
|
||||
if(soft)++expected_failures;
|
||||
std::cout << "checking value of " << name << "...failed" << std::endl;
|
||||
std::cout << "\tfound: " << n << " expected " << o << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct type_checker
|
||||
{
|
||||
static void check(const char* TT, const char* TU, const char* expression)
|
||||
{
|
||||
++test_count;
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
if((typeid(T) != typeid(U))
|
||||
|| (::boost::is_reference<T>::value != ::boost::is_reference<U>::value)
|
||||
|| (::boost::is_const<T>::value != ::boost::is_const<U>::value)
|
||||
|| (::boost::is_volatile<T>::value != ::boost::is_volatile<U>::value))
|
||||
{
|
||||
#endif
|
||||
++failures;
|
||||
std::cout << "checking type of " << expression << "...failed" << std::endl;
|
||||
std::cout << " expected type was " << TT << std::endl;
|
||||
std::cout << " typeid(" << TT << ") was: " << typeid(T).name() << std::endl;
|
||||
std::cout << " typeid(" << TU << ") was: " << typeid(U).name() << std::endl;
|
||||
std::cout << " In template class " << typeid(type_checker<T,U>).name() << std::endl;
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct type_checker<T,T>
|
||||
{
|
||||
static void check(const char*, const char*, const char*)
|
||||
{
|
||||
++test_count;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#define value_test(v, x) checker<(v == x)>::check(v, x, #x, false);
|
||||
#define soft_value_test(v, x) checker<(v == x)>::check(v, x, #x, true);
|
||||
|
||||
#define value_fail(v, x) \
|
||||
++test_count; \
|
||||
++failures; \
|
||||
std::cout << "checking value of " << #x << "...failed" << std::endl; \
|
||||
std::cout << " " #x " does not compile on this compiler" << std::endl;
|
||||
|
||||
|
||||
#define type_test(v, x) type_checker<v,x>::check(#v, #x, #x);
|
||||
#define type_test3(v, x, z) type_checker<v,x,z>::check(#v, #x "," #z, #x "," #z);
|
||||
#ifndef SHORT_TRANSFORM_TEST
|
||||
#define transform_check(name, from_suffix, to_suffix)\
|
||||
type_test(bool to_suffix, name<bool from_suffix>::type);\
|
||||
type_test(char to_suffix, name<char from_suffix>::type);\
|
||||
type_test(wchar_t to_suffix, name<wchar_t from_suffix>::type);\
|
||||
type_test(signed char to_suffix, name<signed char from_suffix>::type);\
|
||||
type_test(unsigned char to_suffix, name<unsigned char from_suffix>::type);\
|
||||
type_test(short to_suffix, name<short from_suffix>::type);\
|
||||
type_test(unsigned short to_suffix, name<unsigned short from_suffix>::type);\
|
||||
type_test(int to_suffix, name<int from_suffix>::type);\
|
||||
type_test(unsigned int to_suffix, name<unsigned int from_suffix>::type);\
|
||||
type_test(long to_suffix, name<long from_suffix>::type);\
|
||||
type_test(unsigned long to_suffix, name<unsigned long from_suffix>::type);\
|
||||
type_test(float to_suffix, name<float from_suffix>::type);\
|
||||
type_test(long double to_suffix, name<long double from_suffix>::type);\
|
||||
type_test(double to_suffix, name<double from_suffix>::type);\
|
||||
type_test(UDT to_suffix, name<UDT from_suffix>::type);\
|
||||
type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
|
||||
#else
|
||||
#define transform_check(name, from_suffix, to_suffix)\
|
||||
type_test(int to_suffix, name<int from_suffix>::type);\
|
||||
type_test(UDT to_suffix, name<UDT from_suffix>::type);\
|
||||
type_test(enum1 to_suffix, name<enum1 from_suffix>::type);
|
||||
#endif
|
||||
|
||||
#define boost_dummy_macro_param
|
||||
|
||||
template <class T>
|
||||
struct test_align
|
||||
{
|
||||
struct padded
|
||||
{
|
||||
char c;
|
||||
T t;
|
||||
};
|
||||
static void do_it()
|
||||
{
|
||||
padded p;
|
||||
unsigned a = reinterpret_cast<char*>(&(p.t)) - reinterpret_cast<char*>(&p);
|
||||
++test_count;
|
||||
// only fail if we do not have a multiple of the actual value:
|
||||
if((a > ::boost::alignment_of<T>::value) || (a % ::boost::alignment_of<T>::value))
|
||||
{
|
||||
++failures;
|
||||
std::cout << "checking value of " << typeid(boost::alignment_of<T>).name() << "...failed" << std::endl;
|
||||
std::cout << "\tfound: " << boost::alignment_of<T>::value << " expected " << a << std::endl;
|
||||
}
|
||||
// suppress warnings about unused variables:
|
||||
(void)p;
|
||||
(void)a;
|
||||
}
|
||||
};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct test_align<T&>
|
||||
{
|
||||
static void do_it()
|
||||
{
|
||||
//
|
||||
// we can't do the usual test because we can't take the address
|
||||
// of a reference, so check that the result is the same as for a
|
||||
// pointer type instead:
|
||||
unsigned a = boost::alignment_of<T*>::value;
|
||||
++test_count;
|
||||
if(a != boost::alignment_of<T&>::value)
|
||||
{
|
||||
++failures;
|
||||
std::cout << "checking value of " << typeid(boost::alignment_of<T&>).name() << "...failed" << std::endl;
|
||||
std::cout << "\tfound: " << boost::alignment_of<T&>::value << " expected " << a << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#define align_test(T) test_align<T>::do_it()
|
||||
|
||||
//
|
||||
// the following code allows us to test that a particular
|
||||
// template functions correctly when instanciated inside another template
|
||||
// (some bugs only show up in that situation). For each template
|
||||
// we declare one NESTED_DECL(classname) that sets up the template class
|
||||
// and multiple NESTED_TEST(classname, template-arg) declarations, to carry
|
||||
// the actual tests:
|
||||
template <bool b>
|
||||
struct nested_test
|
||||
{
|
||||
typedef nested_test type;
|
||||
bool run_time_value;
|
||||
const char* what;
|
||||
nested_test(bool b2, const char* w) : run_time_value(b2), what(w) { check(); }
|
||||
void check()
|
||||
{
|
||||
++test_count;
|
||||
if(b != run_time_value)
|
||||
{
|
||||
++failures;
|
||||
std::cerr << "Mismatch between runtime and compile time values in " << what << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define NESTED_DECL(what)\
|
||||
template <class T> \
|
||||
struct BOOST_TT_JOIN(nested_tester_,what){\
|
||||
nested_test< (0 != ::boost::what<T>::value)> tester;\
|
||||
BOOST_TT_JOIN(nested_tester_,what)(const char* s) : tester(::boost::what<T>::value, s){}\
|
||||
};
|
||||
#define NESTED_TEST(what, with)\
|
||||
{BOOST_TT_JOIN(nested_tester_,what)<with> check(#what "<" #with ">"); (void)check;}
|
||||
|
||||
#define BOOST_TT_JOIN( X, Y ) BOOST_DO_TT_JOIN( X, Y )
|
||||
#define BOOST_DO_TT_JOIN( X, Y ) X##Y
|
||||
|
||||
|
||||
|
||||
//
|
||||
// define some types to test with:
|
||||
//
|
||||
enum enum_UDT{ one, two, three };
|
||||
struct UDT
|
||||
{
|
||||
UDT(){};
|
||||
~UDT(){};
|
||||
UDT(const UDT&);
|
||||
UDT& operator=(const UDT&);
|
||||
int i;
|
||||
|
||||
void f1();
|
||||
int f2();
|
||||
int f3(int);
|
||||
int f4(int, float);
|
||||
};
|
||||
|
||||
typedef void(*f1)();
|
||||
typedef int(*f2)(int);
|
||||
typedef int(*f3)(int, bool);
|
||||
typedef void (UDT::*mf1)();
|
||||
typedef int (UDT::*mf2)();
|
||||
typedef int (UDT::*mf3)(int);
|
||||
typedef int (UDT::*mf4)(int, float);
|
||||
typedef int (UDT::*mp);
|
||||
|
||||
// cv-qualifiers applied to reference types should have no effect
|
||||
// declare these here for later use with is_reference and remove_reference:
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4181)
|
||||
# endif // BOOST_MSVC
|
||||
typedef int& r_type;
|
||||
typedef const r_type cr_type;
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
# endif // BOOST_MSVC
|
||||
|
||||
struct POD_UDT { int x; };
|
||||
struct empty_UDT{ ~empty_UDT(){}; };
|
||||
struct empty_POD_UDT{};
|
||||
union union_UDT
|
||||
{
|
||||
int x;
|
||||
double y;
|
||||
~union_UDT();
|
||||
};
|
||||
union POD_union_UDT
|
||||
{
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
union empty_union_UDT
|
||||
{
|
||||
~empty_union_UDT();
|
||||
};
|
||||
union empty_POD_union_UDT{};
|
||||
|
||||
class Base { };
|
||||
|
||||
class Deriverd : public Base { };
|
||||
|
||||
class NonDerived { };
|
||||
|
||||
enum enum1
|
||||
{
|
||||
one_,two_
|
||||
};
|
||||
|
||||
enum enum2
|
||||
{
|
||||
three_,four_
|
||||
};
|
||||
|
||||
struct VB
|
||||
{
|
||||
virtual ~VB(){};
|
||||
};
|
||||
|
||||
struct VD : VB
|
||||
{
|
||||
~VD(){};
|
||||
};
|
||||
//
|
||||
// struct non_pointer:
|
||||
// used to verify that is_pointer does not return
|
||||
// true for class types that implement operator void*()
|
||||
//
|
||||
struct non_pointer
|
||||
{
|
||||
operator void*(){return this;}
|
||||
};
|
||||
struct non_int_pointer
|
||||
{
|
||||
int i;
|
||||
operator int*(){return &i;}
|
||||
};
|
||||
struct int_constructible
|
||||
{
|
||||
int_constructible(int);
|
||||
};
|
||||
struct int_convertible
|
||||
{
|
||||
operator int();
|
||||
};
|
||||
//
|
||||
// struct non_empty:
|
||||
// used to verify that is_empty does not emit
|
||||
// spurious warnings or errors.
|
||||
//
|
||||
struct non_empty : boost::noncopyable
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_TEST_HPP
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
44
tests/alignment_test.cpp
Normal file
44
tests/alignment_test.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/alignment_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
NESTED_DECL(alignment_of)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NESTED_TEST(alignment_of, int)
|
||||
NESTED_TEST(alignment_of, int_constructible)
|
||||
|
||||
align_test(int);
|
||||
align_test(char);
|
||||
align_test(double);
|
||||
align_test(int[4]);
|
||||
align_test(int(*)(int));
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
align_test(char&);
|
||||
align_test(char (&)(int));
|
||||
align_test(char(&)[4]);
|
||||
#endif
|
||||
align_test(int*);
|
||||
//align_test(const int);
|
||||
align_test(VB);
|
||||
align_test(VD);
|
||||
value_test(0, ::boost::alignment_of<void>::value);
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
unsigned int expected_failures = 0;
|
||||
|
197
tests/arithmetic_traits_test.cpp
Normal file
197
tests/arithmetic_traits_test.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
NESTED_DECL(is_void)
|
||||
NESTED_DECL(is_integral)
|
||||
NESTED_DECL(is_float)
|
||||
NESTED_DECL(is_arithmetic)
|
||||
NESTED_DECL(is_fundamental)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NESTED_TEST(is_void, void)
|
||||
NESTED_TEST(is_void, int)
|
||||
NESTED_TEST(is_integral, int)
|
||||
NESTED_TEST(is_integral, float)
|
||||
NESTED_TEST(is_float, void)
|
||||
NESTED_TEST(is_float, double)
|
||||
NESTED_TEST(is_arithmetic, void)
|
||||
NESTED_TEST(is_arithmetic, int)
|
||||
NESTED_TEST(is_fundamental, UDT)
|
||||
NESTED_TEST(is_fundamental, int)
|
||||
|
||||
value_test(true, boost::is_void<void>::value)
|
||||
value_test(true, boost::is_void<const void>::value)
|
||||
value_test(true, boost::is_void<volatile void>::value)
|
||||
value_test(true, boost::is_void<const volatile void>::value)
|
||||
value_test(false, boost::is_void<int>::value)
|
||||
|
||||
value_test(false, boost::is_integral<UDT>::value)
|
||||
value_test(false, boost::is_integral<void>::value)
|
||||
value_test(true, boost::is_integral<bool>::value)
|
||||
value_test(true, boost::is_integral<char>::value)
|
||||
value_test(true, boost::is_integral<signed char>::value)
|
||||
value_test(true, boost::is_integral<unsigned char>::value)
|
||||
value_test(true, boost::is_integral<wchar_t>::value)
|
||||
value_test(true, boost::is_integral<short>::value)
|
||||
value_test(true, boost::is_integral<unsigned short>::value)
|
||||
value_test(true, boost::is_integral<int>::value)
|
||||
value_test(true, boost::is_integral<unsigned int>::value)
|
||||
value_test(true, boost::is_integral<long>::value)
|
||||
value_test(true, boost::is_integral<unsigned long>::value)
|
||||
value_test(false, boost::is_integral<float>::value)
|
||||
value_test(false, boost::is_integral<double>::value)
|
||||
value_test(false, boost::is_integral<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_integral<long long>::value)
|
||||
value_test(true, boost::is_integral<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_integral<__int64>::value)
|
||||
value_test(true, boost::is_integral<unsigned __int64>::value)
|
||||
#endif
|
||||
//const qualified ints:
|
||||
value_test(true, boost::is_integral<const bool>::value)
|
||||
value_test(true, boost::is_integral<const char>::value)
|
||||
value_test(true, boost::is_integral<const signed char>::value)
|
||||
value_test(true, boost::is_integral<const unsigned char>::value)
|
||||
value_test(true, boost::is_integral<const wchar_t>::value)
|
||||
value_test(true, boost::is_integral<const short>::value)
|
||||
value_test(true, boost::is_integral<const unsigned short>::value)
|
||||
value_test(true, boost::is_integral<const int>::value)
|
||||
value_test(true, boost::is_integral<const unsigned int>::value)
|
||||
value_test(true, boost::is_integral<const long>::value)
|
||||
value_test(true, boost::is_integral<const unsigned long>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_integral<const long long>::value)
|
||||
value_test(true, boost::is_integral<const unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_integral<const __int64>::value)
|
||||
value_test(true, boost::is_integral<const unsigned __int64>::value)
|
||||
#endif
|
||||
// volatile qualified ints:
|
||||
value_test(true, boost::is_integral<volatile bool>::value)
|
||||
value_test(true, boost::is_integral<volatile char>::value)
|
||||
value_test(true, boost::is_integral<volatile signed char>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned char>::value)
|
||||
value_test(true, boost::is_integral<volatile wchar_t>::value)
|
||||
value_test(true, boost::is_integral<volatile short>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned short>::value)
|
||||
value_test(true, boost::is_integral<volatile int>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned int>::value)
|
||||
value_test(true, boost::is_integral<volatile long>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned long>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_integral<volatile long long>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_integral<volatile __int64>::value)
|
||||
value_test(true, boost::is_integral<volatile unsigned __int64>::value)
|
||||
#endif
|
||||
//const qualified ints:
|
||||
value_test(true, boost::is_integral<const volatile bool>::value)
|
||||
value_test(true, boost::is_integral<const volatile char>::value)
|
||||
value_test(true, boost::is_integral<const volatile signed char>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned char>::value)
|
||||
value_test(true, boost::is_integral<const volatile wchar_t>::value)
|
||||
value_test(true, boost::is_integral<const volatile short>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned short>::value)
|
||||
value_test(true, boost::is_integral<const volatile int>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned int>::value)
|
||||
value_test(true, boost::is_integral<const volatile long>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned long>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_integral<const volatile long long>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_integral<const volatile __int64>::value)
|
||||
value_test(true, boost::is_integral<const volatile unsigned __int64>::value)
|
||||
#endif
|
||||
value_test(true, boost::is_float<const volatile float>::value)
|
||||
value_test(true, boost::is_float<const volatile double>::value)
|
||||
value_test(true, boost::is_float<const volatile long double>::value)
|
||||
value_test(true, boost::is_float<volatile float>::value)
|
||||
value_test(true, boost::is_float<volatile double>::value)
|
||||
value_test(true, boost::is_float<volatile long double>::value)
|
||||
value_test(true, boost::is_float<const float>::value)
|
||||
value_test(true, boost::is_float<const double>::value)
|
||||
value_test(true, boost::is_float<const long double>::value)
|
||||
value_test(true, boost::is_float<float>::value)
|
||||
value_test(true, boost::is_float<double>::value)
|
||||
value_test(true, boost::is_float<long double>::value)
|
||||
value_test(false, boost::is_float<int>::value)
|
||||
value_test(false, boost::is_float<void>::value)
|
||||
value_test(false, boost::is_float<UDT>::value)
|
||||
|
||||
|
||||
value_test(false, boost::is_arithmetic<UDT>::value)
|
||||
value_test(false, boost::is_arithmetic<void>::value)
|
||||
value_test(true, boost::is_arithmetic<bool>::value)
|
||||
value_test(true, boost::is_arithmetic<char>::value)
|
||||
value_test(true, boost::is_arithmetic<signed char>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned char>::value)
|
||||
value_test(true, boost::is_arithmetic<wchar_t>::value)
|
||||
value_test(true, boost::is_arithmetic<short>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned short>::value)
|
||||
value_test(true, boost::is_arithmetic<int>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned int>::value)
|
||||
value_test(true, boost::is_arithmetic<long>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned long>::value)
|
||||
value_test(true, boost::is_arithmetic<float>::value)
|
||||
value_test(true, boost::is_arithmetic<double>::value)
|
||||
value_test(true, boost::is_arithmetic<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_arithmetic<long long>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_arithmetic<__int64>::value)
|
||||
value_test(true, boost::is_arithmetic<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, boost::is_fundamental<UDT>::value)
|
||||
value_test(true, boost::is_fundamental<void>::value)
|
||||
value_test(true, boost::is_fundamental<bool>::value)
|
||||
value_test(true, boost::is_fundamental<char>::value)
|
||||
value_test(true, boost::is_fundamental<signed char>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned char>::value)
|
||||
value_test(true, boost::is_fundamental<wchar_t>::value)
|
||||
value_test(true, boost::is_fundamental<short>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned short>::value)
|
||||
value_test(true, boost::is_fundamental<int>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned int>::value)
|
||||
value_test(true, boost::is_fundamental<long>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned long>::value)
|
||||
value_test(true, boost::is_fundamental<float>::value)
|
||||
value_test(true, boost::is_fundamental<double>::value)
|
||||
value_test(true, boost::is_fundamental<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, boost::is_fundamental<long long>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, boost::is_fundamental<__int64>::value)
|
||||
value_test(true, boost::is_fundamental<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
unsigned int expected_failures = 0;
|
||||
|
116
tests/composite_traits_test.cpp
Normal file
116
tests/composite_traits_test.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
NESTED_DECL(is_array)
|
||||
NESTED_DECL(is_pointer)
|
||||
NESTED_DECL(is_reference)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NESTED_TEST(is_array, int)
|
||||
NESTED_TEST(is_array, int[2])
|
||||
NESTED_TEST(is_array, int[3][4])
|
||||
NESTED_TEST(is_array, int const [5])
|
||||
NESTED_TEST(is_array, int(&)[2])
|
||||
NESTED_TEST(is_array, int (*)(double))
|
||||
NESTED_TEST(is_pointer, int)
|
||||
NESTED_TEST(is_pointer, int*)
|
||||
NESTED_TEST(is_reference, int)
|
||||
NESTED_TEST(is_reference, int&)
|
||||
|
||||
value_test(false, boost::is_array<int>::value)
|
||||
value_test(false, boost::is_array<int*>::value)
|
||||
value_test(false, boost::is_array<const int*>::value)
|
||||
value_test(false, boost::is_array<const volatile int*>::value)
|
||||
value_test(false, boost::is_array<int*const>::value)
|
||||
value_test(false, boost::is_array<const int*volatile>::value)
|
||||
value_test(false, boost::is_array<const volatile int*const>::value)
|
||||
value_test(true, boost::is_array<int[2]>::value)
|
||||
value_test(true, boost::is_array<const int[2]>::value)
|
||||
value_test(true, boost::is_array<const volatile int[2]>::value)
|
||||
value_test(true, boost::is_array<int[2][3]>::value)
|
||||
value_test(true, boost::is_array<UDT[2]>::value)
|
||||
value_test(false, boost::is_array<int(&)[2]>::value)
|
||||
value_test(false, boost::is_array<f1>::value)
|
||||
value_test(false, boost::is_array<void>::value)
|
||||
|
||||
value_test(false, boost::is_pointer<int>::value)
|
||||
value_test(false, boost::is_pointer<int&>::value)
|
||||
value_test(true, boost::is_pointer<int*>::value)
|
||||
value_test(true, boost::is_pointer<const int*>::value)
|
||||
value_test(true, boost::is_pointer<volatile int*>::value)
|
||||
value_test(true, boost::is_pointer<non_pointer*>::value)
|
||||
// these were false in previous versions (JM 20 Dec 2000):
|
||||
value_test(true, boost::is_pointer<int*const>::value)
|
||||
value_test(true, boost::is_pointer<int*volatile>::value)
|
||||
value_test(true, boost::is_pointer<int*const volatile>::value)
|
||||
// JM 02 Oct 2000:
|
||||
value_test(false, boost::is_pointer<non_pointer>::value)
|
||||
value_test(false, boost::is_pointer<int*&>::value)
|
||||
value_test(false, boost::is_pointer<int(&)[2]>::value)
|
||||
value_test(false, boost::is_pointer<int[2]>::value)
|
||||
value_test(false, boost::is_pointer<char[sizeof(void*)]>::value)
|
||||
value_test(false, boost::is_pointer<void>::value)
|
||||
|
||||
value_test(true, boost::is_pointer<f1>::value)
|
||||
value_test(true, boost::is_pointer<f2>::value)
|
||||
value_test(true, boost::is_pointer<f3>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3
|
||||
value_test(false, boost::is_pointer<mf1>::value)
|
||||
value_test(false, boost::is_pointer<mf2>::value)
|
||||
value_test(false, boost::is_pointer<mf3>::value)
|
||||
value_test(false, boost::is_pointer<mf4>::value)
|
||||
|
||||
value_test(false, boost::is_reference<bool>::value)
|
||||
value_test(true, boost::is_reference<int&>::value)
|
||||
value_test(true, boost::is_reference<const int&>::value)
|
||||
value_test(true, boost::is_reference<volatile int &>::value)
|
||||
value_test(true, boost::is_reference<const volatile int &>::value)
|
||||
value_test(true, boost::is_reference<r_type>::value)
|
||||
value_test(true, boost::is_reference<cr_type>::value)
|
||||
value_test(true, boost::is_reference<const UDT&>::value)
|
||||
value_test(false, boost::is_reference<void>::value)
|
||||
|
||||
value_test(false, boost::is_member_pointer<f1>::value)
|
||||
value_test(false, boost::is_member_pointer<f2>::value)
|
||||
value_test(false, boost::is_member_pointer<f3>::value)
|
||||
value_test(false, boost::is_member_pointer<void*>::value)
|
||||
value_test(true, boost::is_member_pointer<mf1>::value)
|
||||
value_test(true, boost::is_member_pointer<mf2>::value)
|
||||
value_test(true, boost::is_member_pointer<mf3>::value)
|
||||
value_test(true, boost::is_member_pointer<mf4>::value)
|
||||
value_test(false, boost::is_member_pointer<void>::value)
|
||||
|
||||
value_test(false, boost::is_enum<int>::value)
|
||||
value_test(true, boost::is_enum<enum_UDT>::value)
|
||||
value_test(false, boost::is_enum<int_convertible>::value)
|
||||
value_test(false, boost::is_enum<int&>::value)
|
||||
value_test(false, boost::is_enum<void>::value)
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef __BORLANDC__
|
||||
unsigned int expected_failures = 2;
|
||||
#elif defined(__GNUC__)
|
||||
unsigned int expected_failures = 1; // can't handle cv-qualified references
|
||||
#elif defined(BOOST_MSVC)
|
||||
unsigned int expected_failures = 1;
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
||||
|
50
tests/cv_traits_test.cpp
Normal file
50
tests/cv_traits_test.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
NESTED_DECL(is_const)
|
||||
NESTED_DECL(is_volatile)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NESTED_TEST(is_const, int)
|
||||
NESTED_TEST(is_const, const int)
|
||||
NESTED_TEST(is_const, volatile int)
|
||||
NESTED_TEST(is_volatile, int)
|
||||
NESTED_TEST(is_volatile, const int)
|
||||
NESTED_TEST(is_volatile, volatile int)
|
||||
|
||||
value_test(false, boost::is_const<void>::value)
|
||||
value_test(true, boost::is_const<const void>::value)
|
||||
value_test(false, boost::is_const<int>::value)
|
||||
value_test(true, boost::is_const<const int>::value)
|
||||
value_test(true, boost::is_const<const UDT>::value)
|
||||
value_test(true, boost::is_const<const volatile UDT>::value)
|
||||
value_test(false, boost::is_volatile<void>::value)
|
||||
value_test(true, boost::is_volatile<volatile void>::value)
|
||||
value_test(false, boost::is_volatile<int>::value)
|
||||
value_test(true, boost::is_volatile<volatile int>::value)
|
||||
value_test(true, boost::is_volatile<volatile UDT>::value)
|
||||
value_test(true, boost::is_volatile<volatile UDT>::value)
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef BOOST_MSVC
|
||||
unsigned int expected_failures = 2;
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
72
tests/is_convertible_test.cpp
Normal file
72
tests/is_convertible_test.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/conversion_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
value_test(true, (boost::is_convertible<Deriverd,Base>::value));
|
||||
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
|
||||
value_test(true, (boost::is_convertible<Base,Base>::value));
|
||||
value_test(false, (boost::is_convertible<Base,Deriverd>::value));
|
||||
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
|
||||
value_test(false, (boost::is_convertible<NonDerived,Base>::value));
|
||||
value_test(false, (boost::is_convertible<boost::noncopyable, int>::value));
|
||||
value_test(true, (boost::is_convertible<float,int>::value));
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
value_test(false, (boost::is_convertible<float,void>::value));
|
||||
value_test(false, (boost::is_convertible<void,float>::value));
|
||||
value_test(true, (boost::is_convertible<void,void>::value));
|
||||
#endif
|
||||
value_test(true, (boost::is_convertible<enum1, int>::value));
|
||||
value_test(true, (boost::is_convertible<Deriverd*, Base*>::value));
|
||||
value_test(false, (boost::is_convertible<Base*, Deriverd*>::value));
|
||||
value_test(true, (boost::is_convertible<Deriverd&, Base&>::value));
|
||||
value_test(false, (boost::is_convertible<Base&, Deriverd&>::value));
|
||||
value_test(true, (boost::is_convertible<const Deriverd*, const Base*>::value));
|
||||
value_test(false, (boost::is_convertible<const Base*, const Deriverd*>::value));
|
||||
value_test(true, (boost::is_convertible<const Deriverd&, const Base&>::value));
|
||||
value_test(false, (boost::is_convertible<const Base&, const Deriverd&>::value));
|
||||
|
||||
value_test(false, (boost::is_convertible<const int *, int*>::value));
|
||||
value_test(false, (boost::is_convertible<const int&, int&>::value));
|
||||
value_test(true, (boost::is_convertible<int*, int[2]>::value));
|
||||
value_test(false, (boost::is_convertible<const int*, int[3]>::value));
|
||||
value_test(true, (boost::is_convertible<const int&, int>::value));
|
||||
value_test(true, (boost::is_convertible<int(&)[4], const int*>::value));
|
||||
value_test(true, (boost::is_convertible<int(&)(int), int(*)(int)>::value));
|
||||
value_test(true, (boost::is_convertible<int *, const int*>::value));
|
||||
value_test(true, (boost::is_convertible<int&, const int&>::value));
|
||||
value_test(true, (boost::is_convertible<int[2], int*>::value));
|
||||
value_test(true, (boost::is_convertible<int[2], const int*>::value));
|
||||
value_test(false, (boost::is_convertible<const int[2], int*>::value));
|
||||
|
||||
value_test(true, (boost::is_convertible<non_pointer, void*>::value));
|
||||
value_test(false, (boost::is_convertible<non_pointer, int*>::value));
|
||||
value_test(true, (boost::is_convertible<non_int_pointer, int*>::value));
|
||||
value_test(true, (boost::is_convertible<non_int_pointer, void*>::value));
|
||||
value_test(true, (boost::is_convertible<int, int_constructible>::value));
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef __BORLANDC__
|
||||
unsigned int expected_failures = 1;
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
42
tests/is_same_test.cpp
Normal file
42
tests/is_same_test.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
value_test(true, (::boost::is_same<int, int>::value))
|
||||
value_test(false, (::boost::is_same<int, const int>::value))
|
||||
value_test(false, (::boost::is_same<int, int&>::value))
|
||||
value_test(false, (::boost::is_same<const int, int&>::value))
|
||||
value_test(false, (::boost::is_same<int, const int&>::value))
|
||||
value_test(false, (::boost::is_same<int*, const int*>::value))
|
||||
value_test(false, (::boost::is_same<int*, int*const>::value))
|
||||
value_test(false, (::boost::is_same<int, int[2]>::value))
|
||||
value_test(false, (::boost::is_same<int*, int[2]>::value))
|
||||
value_test(false, (::boost::is_same<int[4], int[2]>::value))
|
||||
value_test(false, (::boost::is_same<void, int>::value))
|
||||
value_test(true, (::boost::is_same<void, void>::value))
|
||||
value_test(false, (::boost::is_same<void, const void>::value))
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef BOOST_MSVC
|
||||
// can't separate void and cv-void:
|
||||
unsigned int expected_failures = 1;
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
191
tests/object_type_traits_test.cpp
Normal file
191
tests/object_type_traits_test.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/object_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
NESTED_DECL(is_class)
|
||||
NESTED_DECL(is_object)
|
||||
NESTED_DECL(is_scalar)
|
||||
NESTED_DECL(is_compound)
|
||||
NESTED_DECL(is_POD)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
NESTED_TEST(is_class, int)
|
||||
NESTED_TEST(is_class, UDT)
|
||||
NESTED_TEST(is_object, int)
|
||||
NESTED_TEST(is_object, void)
|
||||
NESTED_TEST(is_object, UDT)
|
||||
NESTED_TEST(is_scalar, void)
|
||||
NESTED_TEST(is_scalar, int)
|
||||
NESTED_TEST(is_compound, int)
|
||||
NESTED_TEST(is_compound, UDT)
|
||||
NESTED_TEST(is_POD, int)
|
||||
NESTED_TEST(is_POD, UDT)
|
||||
|
||||
value_test(false, boost::is_class<int>::value)
|
||||
value_test(false, boost::is_class<const int>::value)
|
||||
value_test(false, boost::is_class<volatile int>::value)
|
||||
value_test(false, boost::is_class<int*>::value)
|
||||
value_test(false, boost::is_class<int* const>::value)
|
||||
value_test(false, boost::is_class<int[2]>::value)
|
||||
value_test(false, boost::is_class<int&>::value)
|
||||
value_test(false, boost::is_class<mf4>::value)
|
||||
value_test(false, boost::is_class<f1>::value)
|
||||
value_test(false, boost::is_class<enum_UDT>::value)
|
||||
value_test(true, boost::is_class<UDT>::value)
|
||||
value_test(true, boost::is_class<UDT const>::value)
|
||||
value_test(true, boost::is_class<UDT volatile>::value)
|
||||
value_test(true, boost::is_class<empty_UDT>::value)
|
||||
value_test(true, boost::is_class<std::iostream>::value)
|
||||
value_test(false, boost::is_class<UDT*>::value)
|
||||
value_test(false, boost::is_class<UDT[2]>::value)
|
||||
value_test(false, boost::is_class<UDT&>::value)
|
||||
value_test(false, boost::is_class<void>::value)
|
||||
|
||||
value_test(true, boost::is_object<int>::value)
|
||||
value_test(true, boost::is_object<UDT>::value)
|
||||
value_test(false, boost::is_object<int&>::value)
|
||||
value_test(false, boost::is_object<void>::value)
|
||||
|
||||
value_test(true, boost::is_scalar<int>::value)
|
||||
value_test(true, boost::is_scalar<void*>::value)
|
||||
value_test(false, boost::is_scalar<void>::value)
|
||||
value_test(false, boost::is_scalar<UDT>::value)
|
||||
value_test(false, boost::is_scalar<int&>::value)
|
||||
|
||||
value_test(true, boost::is_compound<UDT>::value)
|
||||
value_test(true, boost::is_compound<void*>::value)
|
||||
value_test(false, boost::is_compound<void>::value)
|
||||
value_test(false, boost::is_compound<int>::value)
|
||||
|
||||
value_test(true, boost::is_POD<int>::value)
|
||||
value_test(true, boost::is_POD<int*>::value)
|
||||
value_test(false, boost::is_POD<int&>::value)
|
||||
value_test(true, boost::is_POD<int*const>::value)
|
||||
value_test(true, boost::is_POD<const int>::value)
|
||||
value_test(true, boost::is_POD<volatile int>::value)
|
||||
value_test(false, boost::is_POD<const int&>::value)
|
||||
value_test(true, boost::is_POD<int[2]>::value)
|
||||
value_test(true, boost::is_POD<int[3][2]>::value)
|
||||
value_test(true, boost::is_POD<int[2][4][5][6][3]>::value)
|
||||
value_test(true, boost::is_POD<f1>::value)
|
||||
value_test(true, boost::is_POD<mf2>::value)
|
||||
value_test(false, boost::is_POD<UDT>::value)
|
||||
value_test(false, boost::is_POD<empty_UDT>::value)
|
||||
value_test(true, boost::is_POD<enum_UDT>::value)
|
||||
value_test(true, boost::is_POD<void>::value)
|
||||
|
||||
value_test(true, boost::has_trivial_constructor<int>::value)
|
||||
value_test(true, boost::has_trivial_constructor<int*>::value)
|
||||
value_test(true, boost::has_trivial_constructor<int*const>::value)
|
||||
value_test(true, boost::has_trivial_constructor<const int>::value)
|
||||
value_test(true, boost::has_trivial_constructor<volatile int>::value)
|
||||
value_test(true, boost::has_trivial_constructor<int[2]>::value)
|
||||
value_test(true, boost::has_trivial_constructor<int[3][2]>::value)
|
||||
value_test(true, boost::has_trivial_constructor<int[2][4][5][6][3]>::value)
|
||||
value_test(true, boost::has_trivial_constructor<f1>::value)
|
||||
value_test(true, boost::has_trivial_constructor<mf2>::value)
|
||||
value_test(false, boost::has_trivial_constructor<UDT>::value)
|
||||
value_test(true, boost::has_trivial_constructor<empty_UDT>::value)
|
||||
value_test(true, boost::has_trivial_constructor<enum_UDT>::value)
|
||||
value_test(true, boost::has_trivial_constructor<void>::value)
|
||||
|
||||
value_test(true, boost::has_trivial_copy<int>::value)
|
||||
value_test(true, boost::has_trivial_copy<int*>::value)
|
||||
value_test(true, boost::has_trivial_copy<int*const>::value)
|
||||
value_test(true, boost::has_trivial_copy<const int>::value)
|
||||
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
|
||||
value_test(false, boost::has_trivial_copy<volatile int>::value)
|
||||
value_test(true, boost::has_trivial_copy<int[2]>::value)
|
||||
value_test(true, boost::has_trivial_copy<int[3][2]>::value)
|
||||
value_test(true, boost::has_trivial_copy<int[2][4][5][6][3]>::value)
|
||||
value_test(true, boost::has_trivial_copy<f1>::value)
|
||||
value_test(true, boost::has_trivial_copy<mf2>::value)
|
||||
value_test(false, boost::has_trivial_copy<UDT>::value)
|
||||
value_test(true, boost::has_trivial_copy<empty_UDT>::value)
|
||||
value_test(true, boost::has_trivial_copy<enum_UDT>::value)
|
||||
value_test(true, boost::has_trivial_copy<void>::value)
|
||||
|
||||
value_test(true, boost::has_trivial_assign<int>::value)
|
||||
value_test(true, boost::has_trivial_assign<int*>::value)
|
||||
value_test(false, boost::has_trivial_assign<int*const>::value)
|
||||
value_test(false, boost::has_trivial_assign<const int>::value)
|
||||
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
|
||||
value_test(false, boost::has_trivial_assign<volatile int>::value)
|
||||
value_test(true, boost::has_trivial_assign<int[2]>::value)
|
||||
value_test(true, boost::has_trivial_assign<int[3][2]>::value)
|
||||
value_test(true, boost::has_trivial_assign<int[2][4][5][6][3]>::value)
|
||||
value_test(true, boost::has_trivial_assign<f1>::value)
|
||||
value_test(true, boost::has_trivial_assign<mf2>::value)
|
||||
value_test(false, boost::has_trivial_assign<UDT>::value)
|
||||
value_test(true, boost::has_trivial_assign<empty_UDT>::value)
|
||||
value_test(true, boost::has_trivial_assign<enum_UDT>::value)
|
||||
value_test(true, boost::has_trivial_assign<void>::value)
|
||||
|
||||
value_test(true, boost::has_trivial_destructor<int>::value)
|
||||
value_test(true, boost::has_trivial_destructor<int*>::value)
|
||||
value_test(true, boost::has_trivial_destructor<int*const>::value)
|
||||
value_test(true, boost::has_trivial_destructor<const int>::value)
|
||||
value_test(true, boost::has_trivial_destructor<volatile int>::value)
|
||||
value_test(true, boost::has_trivial_destructor<int[2]>::value)
|
||||
value_test(true, boost::has_trivial_destructor<int[3][2]>::value)
|
||||
value_test(true, boost::has_trivial_destructor<int[2][4][5][6][3]>::value)
|
||||
value_test(true, boost::has_trivial_destructor<f1>::value)
|
||||
value_test(true, boost::has_trivial_destructor<mf2>::value)
|
||||
value_test(false, boost::has_trivial_destructor<UDT>::value)
|
||||
value_test(false, boost::has_trivial_destructor<empty_UDT>::value)
|
||||
value_test(true, boost::has_trivial_destructor<enum_UDT>::value)
|
||||
value_test(true, boost::has_trivial_destructor<void>::value)
|
||||
|
||||
soft_value_test(false, boost::is_empty<int>::value)
|
||||
soft_value_test(false, boost::is_empty<int*>::value)
|
||||
soft_value_test(false, boost::is_empty<int&>::value)
|
||||
soft_value_test(false, boost::is_empty<void>::value)
|
||||
#if defined(__MWERKS__)
|
||||
// apparent compiler bug causes this to fail to compile:
|
||||
value_fail(false, boost::is_empty<int[2]>::value)
|
||||
#else
|
||||
soft_value_test(false, boost::is_empty<int[2]>::value)
|
||||
#endif
|
||||
soft_value_test(false, boost::is_empty<f1>::value)
|
||||
soft_value_test(false, boost::is_empty<mf1>::value)
|
||||
soft_value_test(false, boost::is_empty<UDT>::value)
|
||||
soft_value_test(true, boost::is_empty<empty_UDT>::value)
|
||||
soft_value_test(true, boost::is_empty<empty_POD_UDT>::value)
|
||||
// this one will not compile on most compilers,
|
||||
// because we can't tell the difference between
|
||||
// unions and classes:
|
||||
value_fail(true, boost::is_empty<empty_union_UDT>::value)
|
||||
soft_value_test(false, boost::is_empty<enum_UDT>::value)
|
||||
soft_value_test(true, boost::is_empty<boost::noncopyable>::value)
|
||||
soft_value_test(false, boost::is_empty<non_empty>::value)
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef __BORLANDC__
|
||||
// can't handle enum's or classes that are POD's
|
||||
unsigned int expected_failures = 10;
|
||||
#elif defined(__GNUC__)
|
||||
// classes that are POD's, or empty:
|
||||
unsigned int expected_failures = 4;
|
||||
#elif defined(BOOST_MSVC)
|
||||
// can't handle classes that are POD's or arrays that are POD's
|
||||
unsigned int expected_failures = 19;
|
||||
#else
|
||||
unsigned int expected_failures = 4;
|
||||
#endif
|
||||
|
||||
|
395
tests/transform_traits_test.cpp
Normal file
395
tests/transform_traits_test.cpp
Normal file
@ -0,0 +1,395 @@
|
||||
|
||||
// (C) Copyright John Maddock 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/type_traits/transform_traits.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
|
||||
//
|
||||
// some of these tests, particularly those involving
|
||||
// the use of the transform_check macro are tantamount
|
||||
// to "compiler-abuse", and actually hide a *lot* of
|
||||
// template test code. To prevent "Internal Compiler Error"
|
||||
// type messages, we have to split these up into lots of
|
||||
// separate functions:
|
||||
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ < 0x550))
|
||||
#define SHORT_TRANSFORM_TEST
|
||||
#endif
|
||||
#include "boost/type_traits/type_traits_test.hpp"
|
||||
|
||||
#define BOOST_DECL_TRANSFORM_TEST(name, type, from, to)\
|
||||
void name(){ transform_check(type, from, to) }
|
||||
#define BOOST_DECL_TRANSFORM_TEST3(name, type, from)\
|
||||
void name(){ transform_check(type, from, boost_dummy_macro_param) }
|
||||
#define BOOST_DECL_TRANSFORM_TEST2(name, type)\
|
||||
void name(){ transform_check(type, boost_dummy_macro_param, boost_dummy_macro_param) }
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_const:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_const_test_1, ::boost::remove_const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_2, ::boost::remove_const, volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_3, ::boost::remove_const, const volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_const_test_4, ::boost::remove_const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_6, ::boost::remove_const, *const, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_7, ::boost::remove_const, *volatile, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_8, ::boost::remove_const, *const volatile, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_9, ::boost::remove_const, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_11, ::boost::remove_const, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_12, ::boost::remove_const, const[2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_13, ::boost::remove_const, volatile[2], volatile[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_14, ::boost::remove_const, const volatile[2], volatile[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_15, ::boost::remove_const, [2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_16, ::boost::remove_const, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_const_test_17, ::boost::remove_const, const*const, const*)
|
||||
|
||||
void check_remove_const()
|
||||
{
|
||||
remove_const_test_1();
|
||||
remove_const_test_2();
|
||||
remove_const_test_3();
|
||||
remove_const_test_4();
|
||||
remove_const_test_6();
|
||||
remove_const_test_7();
|
||||
remove_const_test_8();
|
||||
remove_const_test_9();
|
||||
remove_const_test_11();
|
||||
remove_const_test_12();
|
||||
remove_const_test_13();
|
||||
remove_const_test_14();
|
||||
remove_const_test_15();
|
||||
remove_const_test_16();
|
||||
remove_const_test_17();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_volatile:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_1, ::boost::remove_volatile, const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_volatile_test_2, ::boost::remove_volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_3, ::boost::remove_volatile, const volatile, const)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_volatile_test_4, ::boost::remove_volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_volatile_test_5, ::boost::remove_volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_6, ::boost::remove_volatile, *const, *const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_7, ::boost::remove_volatile, *volatile, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_8, ::boost::remove_volatile, *const volatile, *const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_9, ::boost::remove_volatile, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_10, ::boost::remove_volatile, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_11, ::boost::remove_volatile, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_12, ::boost::remove_volatile, const[2], const[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_13, ::boost::remove_volatile, volatile[2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_14, ::boost::remove_volatile, const volatile[2], const[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_15, ::boost::remove_volatile, [2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_16, ::boost::remove_volatile, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_volatile_test_17, ::boost::remove_volatile, const*volatile, const*)
|
||||
|
||||
void check_remove_volatile()
|
||||
{
|
||||
remove_volatile_test_1();
|
||||
remove_volatile_test_2();
|
||||
remove_volatile_test_3();
|
||||
remove_volatile_test_4();
|
||||
remove_volatile_test_5();
|
||||
remove_volatile_test_6();
|
||||
remove_volatile_test_7();
|
||||
remove_volatile_test_8();
|
||||
remove_volatile_test_9();
|
||||
remove_volatile_test_10();
|
||||
remove_volatile_test_11();
|
||||
remove_volatile_test_12();
|
||||
remove_volatile_test_13();
|
||||
remove_volatile_test_14();
|
||||
remove_volatile_test_15();
|
||||
remove_volatile_test_16();
|
||||
remove_volatile_test_17();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_cv:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_cv_test_1, ::boost::remove_cv, const)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_cv_test_2, ::boost::remove_cv, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_cv_test_3, ::boost::remove_cv, const volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_cv_test_4, ::boost::remove_cv)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_5, ::boost::remove_cv, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_6, ::boost::remove_cv, *const, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_7, ::boost::remove_cv, *volatile, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_8, ::boost::remove_cv, *const volatile, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_9, ::boost::remove_cv, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_10, ::boost::remove_cv, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_11, ::boost::remove_cv, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_12, ::boost::remove_cv, const[2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_13, ::boost::remove_cv, volatile[2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_14, ::boost::remove_cv, const volatile[2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_15, ::boost::remove_cv, [2], [2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_16, ::boost::remove_cv, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_cv_test_17, ::boost::remove_cv, const*volatile, const*)
|
||||
|
||||
void check_remove_cv()
|
||||
{
|
||||
remove_cv_test_1();
|
||||
remove_cv_test_2();
|
||||
remove_cv_test_3();
|
||||
remove_cv_test_4();
|
||||
remove_cv_test_5();
|
||||
remove_cv_test_6();
|
||||
remove_cv_test_7();
|
||||
remove_cv_test_8();
|
||||
remove_cv_test_9();
|
||||
remove_cv_test_10();
|
||||
remove_cv_test_11();
|
||||
remove_cv_test_12();
|
||||
remove_cv_test_13();
|
||||
remove_cv_test_14();
|
||||
remove_cv_test_15();
|
||||
remove_cv_test_16();
|
||||
remove_cv_test_17();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_reference:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_1, ::boost::remove_reference, const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_2, ::boost::remove_reference, volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_reference_test_3, ::boost::remove_reference, &)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_reference_test_4, ::boost::remove_reference)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_5, ::boost::remove_reference, const &, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_6, ::boost::remove_reference, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_7, ::boost::remove_reference, *volatile, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_reference_test_8, ::boost::remove_reference, &)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_9, ::boost::remove_reference, const &, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_10, ::boost::remove_reference, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_11, ::boost::remove_reference, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_12, ::boost::remove_reference, const[2], const[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_reference_test_13, ::boost::remove_reference, (&)[2], [2])
|
||||
|
||||
void check_remove_reference()
|
||||
{
|
||||
remove_reference_test_1();
|
||||
remove_reference_test_2();
|
||||
remove_reference_test_3();
|
||||
remove_reference_test_4();
|
||||
remove_reference_test_5();
|
||||
remove_reference_test_6();
|
||||
remove_reference_test_7();
|
||||
remove_reference_test_8();
|
||||
remove_reference_test_9();
|
||||
remove_reference_test_10();
|
||||
remove_reference_test_11();
|
||||
remove_reference_test_12();
|
||||
remove_reference_test_13();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_bounds:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_1, ::boost::remove_bounds, const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_2, ::boost::remove_bounds, volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_bounds_test_3, ::boost::remove_bounds, [2])
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_bounds_test_4, ::boost::remove_bounds)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_5, ::boost::remove_bounds, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_6, ::boost::remove_bounds, *, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_7, ::boost::remove_bounds, *volatile, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_8, ::boost::remove_bounds, const [2], const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_9, ::boost::remove_bounds, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_10, ::boost::remove_bounds, const*, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_11, ::boost::remove_bounds, volatile*, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_12, ::boost::remove_bounds, const[2][3], const[3])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_bounds_test_13, ::boost::remove_bounds, (&)[2], (&)[2])
|
||||
|
||||
void check_remove_bounds()
|
||||
{
|
||||
remove_bounds_test_1();
|
||||
remove_bounds_test_2();
|
||||
remove_bounds_test_3();
|
||||
remove_bounds_test_4();
|
||||
remove_bounds_test_5();
|
||||
remove_bounds_test_6();
|
||||
remove_bounds_test_7();
|
||||
remove_bounds_test_8();
|
||||
remove_bounds_test_9();
|
||||
remove_bounds_test_10();
|
||||
remove_bounds_test_11();
|
||||
remove_bounds_test_12();
|
||||
remove_bounds_test_13();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for remove_pointer:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_1, ::boost::remove_pointer, const, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_2, ::boost::remove_pointer, volatile, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_pointer_test_3, ::boost::remove_pointer, *)
|
||||
BOOST_DECL_TRANSFORM_TEST2(remove_pointer_test_4, ::boost::remove_pointer)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_5, ::boost::remove_pointer, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_6, ::boost::remove_pointer, &, &)
|
||||
BOOST_DECL_TRANSFORM_TEST3(remove_pointer_test_7, ::boost::remove_pointer, *volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_8, ::boost::remove_pointer, const [2], const[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_9, ::boost::remove_pointer, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_10, ::boost::remove_pointer, const*, const)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_11, ::boost::remove_pointer, volatile*, volatile)
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_12, ::boost::remove_pointer, const[2][3], const[2][3])
|
||||
BOOST_DECL_TRANSFORM_TEST(remove_pointer_test_13, ::boost::remove_pointer, (&)[2], (&)[2])
|
||||
|
||||
void check_remove_pointer()
|
||||
{
|
||||
remove_pointer_test_1();
|
||||
remove_pointer_test_2();
|
||||
remove_pointer_test_3();
|
||||
remove_pointer_test_4();
|
||||
remove_pointer_test_5();
|
||||
remove_pointer_test_6();
|
||||
remove_pointer_test_7();
|
||||
remove_pointer_test_8();
|
||||
remove_pointer_test_9();
|
||||
remove_pointer_test_10();
|
||||
remove_pointer_test_11();
|
||||
remove_pointer_test_12();
|
||||
remove_pointer_test_13();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for add_reference:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_1, ::boost::add_reference, const, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_2, ::boost::add_reference, volatile, volatile&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_3, ::boost::add_reference, *, *&)
|
||||
//BOOST_DECL_TRANSFORM_TEST2(add_reference_test_4, ::boost::add_reference)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_5, ::boost::add_reference, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_6, ::boost::add_reference, &, &)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_7, ::boost::add_reference, *volatile, *volatile&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_8, ::boost::add_reference, const [2], const (&)[2])
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_9, ::boost::add_reference, const &, const&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_10, ::boost::add_reference, const*, const*&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_11, ::boost::add_reference, volatile*, volatile*&)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_12, ::boost::add_reference, const[2][3], const (&)[2][3])
|
||||
BOOST_DECL_TRANSFORM_TEST(add_reference_test_13, ::boost::add_reference, (&)[2], (&)[2])
|
||||
|
||||
void check_add_reference()
|
||||
{
|
||||
add_reference_test_1();
|
||||
add_reference_test_2();
|
||||
add_reference_test_3();
|
||||
//add_reference_test_4();
|
||||
add_reference_test_5();
|
||||
add_reference_test_6();
|
||||
add_reference_test_7();
|
||||
add_reference_test_8();
|
||||
add_reference_test_9();
|
||||
add_reference_test_10();
|
||||
add_reference_test_11();
|
||||
add_reference_test_12();
|
||||
add_reference_test_13();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* tests for add_pointer:
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_1, ::boost::add_pointer, const, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_2, ::boost::add_pointer, volatile, volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_3, ::boost::add_pointer, *, **)
|
||||
//BOOST_DECL_TRANSFORM_TEST2(add_pointer_test_4, ::boost::add_pointer)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_7, ::boost::add_pointer, *volatile, *volatile*)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_10, ::boost::add_pointer, const*, const**)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_11, ::boost::add_pointer, volatile*, volatile**)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_5, ::boost::add_pointer, const &, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_6, ::boost::add_pointer, &, *)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_8, ::boost::add_pointer, const [2], const *)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_9, ::boost::add_pointer, const &, const*)
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_12, ::boost::add_pointer, const[2][3], const (*)[3])
|
||||
BOOST_DECL_TRANSFORM_TEST(add_pointer_test_13, ::boost::add_pointer, (&)[2], *)
|
||||
#endif
|
||||
|
||||
void check_add_pointer()
|
||||
{
|
||||
add_pointer_test_1();
|
||||
add_pointer_test_2();
|
||||
add_pointer_test_3();
|
||||
//add_pointer_test_4();
|
||||
add_pointer_test_7();
|
||||
add_pointer_test_10();
|
||||
add_pointer_test_11();
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
add_pointer_test_5();
|
||||
add_pointer_test_6();
|
||||
add_pointer_test_8();
|
||||
add_pointer_test_9();
|
||||
add_pointer_test_12();
|
||||
add_pointer_test_13();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
check_remove_const();
|
||||
check_remove_volatile();
|
||||
check_remove_cv();
|
||||
check_remove_reference();
|
||||
check_remove_bounds();
|
||||
check_remove_pointer();
|
||||
check_add_reference();
|
||||
check_add_pointer();
|
||||
|
||||
type_test(void, boost::remove_const<void>::type)
|
||||
type_test(void, boost::remove_volatile<void>::type)
|
||||
type_test(void, boost::remove_cv<void>::type)
|
||||
|
||||
type_test(int, boost::remove_reference<cr_type>::type)
|
||||
type_test(void, boost::remove_reference<void>::type)
|
||||
|
||||
type_test(void, boost::remove_bounds<void>::type)
|
||||
type_test(void, boost::remove_pointer<void>::type)
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
|
||||
//
|
||||
// define the number of failures expected for given compilers:
|
||||
#ifdef __BORLANDC__
|
||||
#ifdef SHORT_TRANSFORM_TEST
|
||||
unsigned int expected_failures = 97; // cv-qualifiers
|
||||
#else
|
||||
unsigned int expected_failures = 422; // cv-qualifiers
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
unsigned int expected_failures = 1; // cv-qualified references
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user