From 843a1c08e270d3bfdf623bb0310ab6d3729c5198 Mon Sep 17 00:00:00 2001 From: nobody Date: Tue, 20 Feb 2001 12:17:56 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'unlabeled-1.5.2'. [SVN r9288] --- .gitattributes | 96 +++++++ operators.htm | 597 +++++++++++++++++++++++++++++++++++++++++++ type_traits_test.hpp | 114 +++++++++ 3 files changed, 807 insertions(+) create mode 100644 .gitattributes create mode 100644 operators.htm create mode 100644 type_traits_test.hpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3e84d7c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/operators.htm b/operators.htm new file mode 100644 index 0000000..f97498c --- /dev/null +++ b/operators.htm @@ -0,0 +1,597 @@ + + + + + + +Header boost/operators.hpp Documentation + + + + +

c++boost.gif (8819 bytes)Header +boost/operators.hpp

+

Header boost/operators.hpp supplies +(in namespace boost) several sets of templates:

+ +

These templates define many global operators in terms of a minimal number of +fundamental operators.

+

Arithmetic Operators

+

If, for example, you declare a class like this:

+
+
class MyInt : boost::operators<MyInt>
+{
+    bool operator<(const MyInt& x) const; 
+    bool operator==(const MyInt& x) const;
+    MyInt& operator+=(const MyInt& x);    
+    MyInt& operator-=(const MyInt& x);    
+    MyInt& operator*=(const MyInt& x);    
+    MyInt& operator/=(const MyInt& x);    
+    MyInt& operator%=(const MyInt& x);    
+    MyInt& operator|=(const MyInt& x);    
+    MyInt& operator&=(const MyInt& x);    
+    MyInt& operator^=(const MyInt& x);    
+    MyInt& operator++();    
+    MyInt& operator--();    
+};
+
+

then the operators<> template adds more than a dozen +additional operators, such as operator>, <=, >=, and +.  Two-argument +forms of the templates are also provided to allow interaction with other +types.

+

Dave Abrahams +started the library and contributed the arithmetic operators in boost/operators.hpp.
+Jeremy Siek +contributed the dereference operators and iterator +helpers in boost/operators.hpp.
+Aleksey Gurtovoy +contributed the code to support base class chaining +while remaining backward-compatible with old versions of the library.
+Beman Dawes +contributed test_operators.cpp.

+

Rationale

+

Overloaded operators for class types typically occur in groups. If you can +write x + y, you probably also want to be able to write x += +y. If you can write x < y, you also want x > y, +x >= y, and x <= y. Moreover, unless your class has +really surprising behavior, some of these related operators can be defined in +terms of others (e.g. x >= y <=> !(x < y)). +Replicating this boilerplate for multiple classes is both tedious and +error-prone. The boost/operators.hpp +templates help by generating operators for you at namespace scope based on other +operators you've defined in your class.

+ +

Two-Argument Template Forms

+
+

The arguments to a binary operator commonly have identical types, but it is +not unusual to want to define operators which combine different types. For example, +one might want to multiply a mathematical vector by a scalar. The two-argument +template forms of the arithmetic operator templates are supplied for this +purpose. When applying the two-argument form of a template, the desired return +type of the operators typically determines which of the two types in question +should be derived from the operator template. For example, if the result of T + U +is of type T, then T (not U) should be +derived from addable<T,U>. The comparison templates less_than_comparable<> +and equality_comparable<> +are exceptions to this guideline, since the return type of the operators they +define is bool.

+

On compilers which do not support partial specialization, the two-argument +forms must be specified by using the names shown below with the trailing '2'. +The single-argument forms with the trailing '1' are provided for +symmetry and to enable certain applications of the base +class chaining technique.

+

Arithmetic operators table

+

The requirements for the types used to instantiate operator templates are +specified in terms of expressions which must be valid and by the return type of +the expression. In the following table t and t1 are +values of type T, and u is a value of type U. +Every template in the library other than operators<> +and operators2<> has an additional +optional template parameter B which is not shown in the table, but +is explained below

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
templatetemplate will supplyRequirements
operators<T>All the other <T> templates in this table.All the <T> requirements in this table.
operators<T,U>
+ operators2<T,U>
All the other <T,U> templates in this table, plus incrementable<T> + and decrementable<T>.All the <T,U> requirements in this table*, + plus incrementable<T> and decrementable<T>.
less_than_comparable<T>
+ less_than_comparable1<T>
bool operator>(const T&, const T&) 
+ bool operator<=(const T&, const T&)
+ bool operator>=(const T&, const T&)
t<t1. Return convertible to bool
less_than_comparable<T,U>
+ less_than_comparable2<T,U>
bool operator<=(const T&, const U&)
+ bool operator>=(const T&, const U&)
+ bool operator>(const U&, const T&) 
+ bool operator<(const U&, const T&) 
+ bool operator<=(const U&, const T&)
+ bool operator>=(const U&, const T&)
t<u. Return convertible to bool
+ t>u. Return convertible to bool
equality_comparable<T>
+ equality_comparable1<T>
bool operator!=(const T&, const T&)t==t1. Return convertible to bool
equality_comparable<T,U>
+ equality_comparable2<T,U>
friend bool operator==(const U&, const T&)
+ friend bool operator!=(const U&, const T&)
+ friend bool operator!=( const T&, const U&)
t==u. Return convertible to bool
addable<T>
+ addable1<T>
T operator+(T, const T&)t+=t1. Return convertible to T
addable<T,U>
+ addable2<T,U>
T operator+(T, const U&)
+ T operator+(const U&, T )
t+=u. Return convertible to T
subtractable<T>
+ subtractable1<T>
T operator-(T, const T&)t-=t1. Return convertible to T
subtractable<T,U>
+ subtractable2<T,U>
T operator-(T, const U&)t-=u. Return convertible to T
multipliable<T>
+ multipliable1<T>
T operator*(T, const T&)t*=t1. Return convertible to T
multipliable<T,U>
+ multipliable2<T,U>
T operator*(T, const U&)
+ T operator*(const U&, T )
t*=u. Return convertible to T
dividable<T>
+ dividable1<T>
T operator/(T, const T&)t/=t1. Return convertible to T
dividable<T,U>
+ dividable2<T,U>
T operator/(T, const U&)t/=u. Return convertible to T
modable<T>
+ modable1<T>
T operator%(T, const T&)t%=t1. Return convertible to T
modable<T,U>
+ modable2<T,U>
T operator%(T, const U&)t%=u. Return convertible to T
orable<T>
+ orable1<T>
T operator|(T, const T&)t|=t1. Return convertible to T
orable<T,U>
+ orable2<T,U>
T operator|(T, const U&)
+ T operator|(const U&, T )
t|=u. Return convertible to T
andable<T>
+ andable1<T>
T operator&(T, const T&)t&=t1. Return convertible to T
andable<T,U>
+ andable2<T,U>
T operator&(T, const U&)
+ T operator&(const U&, T)
t&=u. Return convertible to T
xorable<T>
+ xorable1<T>
T operator^(T, const T&)t^=t1. Return convertible to T
xorable<T,U>
+ xorable2<T,U>
T operator^(T, const U&)
+ T operator^(const U&, T )
t^=u. Return convertible to T
incrementable<T>
+ incrementable1<T>
T operator++(T& x, int)T temp(x); ++x; return temp;
+ Return convertible to T
decrementable<T>
+ decrementable1<T>
T operator--(T& x, int)T temp(x); --x; return temp;
+ Return convertible to T
+
+Portability Note: many compilers (e.g. MSVC6.3, +GCC 2.95.2) will not enforce the requirements in this table unless the +operations which depend on them are actually used. This is not +standard-conforming behavior. If you are trying to write portable code it is +important not to rely on this bug. In particular, it would be convenient to +derive all your classes which need binary operators from the operators<> +and operators2<> templates, +regardless of whether they implement all the requirements in the table. Even if +this works with your compiler today, it may not work tomorrow. +

Base Class Chaining and Object Size

+

Every template listed in the table except operators<> +and operators2<> has an additional +optional template parameter B.  If supplied, B +must be a class type; the resulting class will be publicly derived from B. This +can be used to avoid the object size bloat commonly associated with multiple +empty base classes (see the note for users of older +versions below for more details). To provide support for several groups of +operators, use the additional parameter to chain operator templates into a +single-base class hierarchy, as in the following example.

+

Caveat: to chain to a base class which is not a boost operator +template when using the single-argument form of a +boost operator template, you must specify the operator template with the +trailing '1' in its name. Otherwise the library will assume you +mean to define a binary operation combining the class you intend to use as a +base class and the class you're deriving.

+

Borland users: even single-inheritance seems to cause an increase in +object size in some cases. If you are not defining a template, you may get +better object-size performance by avoiding derivation altogether, and instead +explicitly instantiating the operator template as follows: +

+    class myclass // lose the inheritance...
+    {
+        //...
+    };
+    // explicitly instantiate the operators I need.
+    template class less_than_comparable<myclass>;
+    template class equality_comparable<myclass>;
+    template class incrementable<myclass>;
+    template class decrementable<myclass>;
+    template class addable<myclass,long>;
+    template class subtractable<myclass,long>;
+
+
+

Usage example

+
+
template <class T>
+class point    // note: private inheritance is OK here!
+    : boost::addable< point<T>          // point + point
+    , boost::subtractable< point<T>     // point - point
+    , boost::dividable2< point<T>, T    // point / T
+    , boost::multipliable2< point<T>, T // point * T, T * point
+      > > > >
+{
+public:
+    point(T, T);
+    T x() const;
+    T y() const;
+
+    point operator+=(const point&);
+    // point operator+(point, const point&) automatically
+    // generated by addable.
+
+    point operator-=(const point&);
+    // point operator-(point, const point&) automatically
+    // generated by subtractable.
+
+    point operator*=(T);
+    // point operator*(point, const T&) and
+    // point operator*(const T&, point) auto-generated
+    // by multipliable.
+
+    point operator/=(T);
+    // point operator/(point, const T&) auto-generated
+    // by dividable.
+private:
+    T x_;
+    T y_;
+};
+
+// now use the point<> class:
+
+template <class T>
+T length(const point<T> p)
+{
+    return sqrt(p.x()*p.x() + p.y()*p.y());
+}
+
+const point<float> right(0, 1);
+const point<float> up(1, 0);
+const point<float> pi_over_4 = up + right;
+const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
+

Arithmetic operators demonstration and test program

+

The operators_test.cpp +program demonstrates the use of the arithmetic operator templates, and can also +be used to verify correct operation.

+

The test program has been compiled and run successfully with: 

+ +

Dereference operators and iterator helpers

+

The iterator helper templates ease the task +of creating a custom iterator. Similar to arithmetic types, a complete iterator +has many operators that are "redundant" and can be implemented in +terms of the core set of operators.

+

The dereference operators were motivated by the iterator +helpers, but are often useful in non-iterator contexts as well. Many of the +redundant iterator operators are also arithmetic operators, so the iterator +helper classes borrow many of the operators defined above. In fact, only two new +operators need to be defined! (the pointer-to-member operator-> +and the subscript operator[]). +

Notation

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tis the user-defined type for which the operations are + being supplied.
Vis the type which the resulting dereferenceable + type "points to", or the value_type of the custom + iterator.
Dis the type used to index the resulting indexable + type or the difference_type of the custom iterator.
Pis a type which can be dereferenced to access V, + or the pointer type of the custom iterator.
Ris the type returned by indexing the indexable + type or the reference type of the custom iterator.
iis short for static_cast<const T&>(*this), + where this is a pointer to the helper class.
+ Another words, i should be an object of the custom iterator + type.
x,x1,x2are objects of type T.
nis an object of type D.
+

The requirements for the types used to instantiate the dereference operators +and iterator helpers are specified in terms of expressions which must be valid +and their return type. 

+

Dereference operators

+

The dereference operator templates in this table all accept an optional +template parameter (not shown) to be used for base class +chaining. + + + + + + + + + + + + + + + + + + +
templatetemplate will supplyRequirements
dereferenceable<T,P>P operator->() const(&*i.). Return convertible to P.
indexable<T,D,R>R operator[](D n) const*(i + n). Return of type R.
+

Iterator helpers

+

There are three separate iterator helper classes, each for a different +category of iterator. Here is a summary of the core set of operators that the +custom iterator must define, and the extra operators that are created by the +helper classes. For convenience, the helper classes also fill in all of the +typedef's required of iterators by the C++ standard (iterator_category, +value_type, etc.).

+ + + + + + + + + + + + + + + + + + + + + + + +
templatetemplate will supplyRequirements
forward_iterator_helper
+ <T,V,D,P,R>
bool operator!=(const T& x1, const T& x2)
+ T operator++(T& x, int)
+ V* operator->() const
+
x1==x2. Return convertible to bool
+ T temp(x); ++x; return temp;
+ (&*i.). Return convertible to V*.
bidirectional_iterator_helper
+ <T,V,D,P,R>
Same as above, plus
+ T operator--(T& x, int)
Same as above, plus
+ T temp(x); --x; return temp;
random_access_iterator_helper
+ <T,V,D,P,R>
Same as above, plus
+ T operator+(T x, const D&)
+ T operator+(const D& n, T x)
+ T operator-(T x, const D& n)
+ R operator[](D n) const
+ bool operator>(const T& x1, const T& x2) 
+ bool operator<=(const T& x1, const T& x2)
+ bool operator>=(const T& x1, const T& x2)
Same as above, plus
+ x+=n. Return convertible to T
+ x-=n. Return convertible to T
+ x1<x2. Return convertible to bool
+ And to satisfy RandomAccessIterator:
+ x1-x2. Return convertible to D
+

Iterator demonstration and test program

+

The iterators_test.cpp +program demonstrates the use of the iterator templates, and can also be used to +verify correct operation. The following is the custom iterator defined in the +test program. It demonstrates a correct (though trivial) implementation of the +core operations that must be defined in order for the iterator helpers to +"fill in" the rest of the iterator operations.

+
+
template <class T, class R, class P>
+struct test_iter
+  : public boost::random_access_iterator_helper<
+     test_iter<T,R,P>, T, std::ptrdiff_t, P, R>
+{
+  typedef test_iter self;
+  typedef R Reference;
+  typedef std::ptrdiff_t Distance;
+
+public:
+  test_iter(T* i) : _i(i) { }
+  test_iter(const self& x) : _i(x._i) { }
+  self& operator=(const self& x) { _i = x._i; return *this; }
+  Reference operator*() const { return *_i; }
+  self& operator++() { ++_i; return *this; }
+  self& operator--() { --_i; return *this; }
+  self& operator+=(Distance n) { _i += n; return *this; }
+  self& operator-=(Distance n) { _i -= n; return *this; }
+  bool operator==(const self& x) const { return _i == x._i; }
+  bool operator<(const self& x) const { return _i < x._i; }
+  friend Distance operator-(const self& x, const self& y) {
+    return x._i - y._i; 
+  }
+protected:
+  T* _i;
+};
+
+

It has been compiled and run successfully with:

+ +

Jeremy Siek +contributed the iterator operators and helpers.  He also contributed iterators_test.cpp

+
+

Note for users of older versions

+

The changes in the library interface and recommended +usage were motivated by some practical issues described below. The new +version of the library is still backward-compatible with the former one (so +you're not forced change any existing code), but the old usage is +deprecated. Though it was arguably simpler and more intuitive than using base +class chaining, it has been discovered that the old practice of deriving +from multiple operator templates can cause the resulting classes to be much +larger than they should be. Most modern C++ compilers significantly bloat the +size of classes derived from multiple empty base classes, even though the base +classes themselves have no state. For instance, the size of point<int> +from the example above was 12-24 bytes on various compilers +for the Win32 platform, instead of the expected 8 bytes. +

Strictly speaking, it was not the library's fault - the language rules allow +the compiler to apply the empty base class optimization in that situation. In +principle an arbitrary number of empty base classes can be allocated at the same +offset, provided that none of them have a common ancestor (see section 10.5 [class.derived], +par. 5 of the standard). But the language definition also doesn't require +implementations to do the optimization, and few if any of today's compilers +implement it when multiple inheritance is involved. What's worse, it is very +unlikely that implementors will adopt it as a future enhancement to existing +compilers, because it would break binary compatibility between code generated by +two different versions of the same compiler. As Matt Austern said, "One of +the few times when you have the freedom to do this sort of thing is when you're +targeting a new architecture...". On the other hand, many common compilers +will use the empty base optimization for single inheritance hierarchies.

+

Given the importance of the issue for the users of the library (which aims to +be useful for writing light-weight classes like MyInt or point<>), +and the forces described above, we decided to change the library interface so +that the object size bloat could be eliminated even on compilers that support +only the simplest form of the empty base class optimization. The current library +interface is the result of those changes. Though the new usage is a bit more +complicated than the old one, we think it's worth it to make the library more +useful in real world. Alexy Gurtovoy contributed the code which supports the new +usage idiom while allowing the library remain backward-compatible.

+
+

Revised 27 Sep 2000

+

© Copyright David Abrahams and Beman Dawes 1999-2000. Permission to copy, +use, modify, sell and distribute this document is granted provided this +copyright notice appears in all copies. This document is provided "as +is" without express or implied warranty, and with no claim as to its +suitability for any purpose.

+ + + + diff --git a/type_traits_test.hpp b/type_traits_test.hpp new file mode 100644 index 0000000..e86b83e --- /dev/null +++ b/type_traits_test.hpp @@ -0,0 +1,114 @@ +// boost::compressed_pair test program + +// (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_test.cpp/call_traits_test.cpp/compressed_pair_test.cpp + + +#ifndef BOOST_TYPE_TRAITS_TEST_HPP +#define BOOST_TYPE_TRAITS_TEST_HPP + +// Variable declarations must come before test_align due to two-phase lookup +unsigned failures = 0; +unsigned test_count = 0; + +// +// this one is here just to suppress warnings: +// +template +bool do_compare(T i, T j) +{ + return i == j; +} + +// +// this one is to verify that a constant is indeed a +// constant-integral-expression: +// +template +struct ct_checker +{ +}; + +#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2(X, Y) X##Y +#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) + +#ifdef BOOST_MSVC +#define value_test(v, x) ++test_count;\ + {typedef ct_checker<(x)> this_is_a_compile_time_check_;}\ + if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;} +#else +#define value_test(v, x) ++test_count;\ + typedef ct_checker<(x)> BOOST_JOIN(this_is_a_compile_time_check_, __LINE__);\ + if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;} +#endif +#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl; + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#define type_test(v, x) ++test_count;\ + if(do_compare(boost::is_same::value, false)){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << typeid(boost::is_same).name() << "::value is false" << std::endl; } +#else +#define type_test(v, x) ++test_count;\ + if(typeid(v) != typeid(x)){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; } +#endif + +template +struct test_align +{ + struct padded + { + char c; + T t; + }; + static void do_it() + { + padded p; + unsigned a = reinterpret_cast(&(p.t)) - reinterpret_cast(&p); + value_test(a, boost::alignment_of::value); + } +}; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct test_align +{ + 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: + value_test(boost::alignment_of::value, boost::alignment_of::value); + } +}; +#endif + +#define align_test(T) test_align::do_it() + +// +// define tests here + +// +// turn off some warnings: +#ifdef __BORLANDC__ +#pragma option -w-8004 +#endif + +#ifdef BOOST_MSVC +#pragma warning (disable: 4018) +#endif + + +#endif // BOOST_TYPE_TRAITS_TEST_HPP +