diff --git a/c++_type_traits.htm b/c++_type_traits.htm
new file mode 100644
index 0000000..59f188d
--- /dev/null
+++ b/c++_type_traits.htm
@@ -0,0 +1,590 @@
+
+
+
+
+
+
+C++ Type traits
+
+
+
+
+C++ Type traits
+
+by John Maddock and Steve Cleary
+
+This is the draft version of an article
+that appeared in the October 2000 issue of Dr Dobb's Journal
+
+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.
+
+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 strlen and wcslen 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 char and wchar_t into the class char_traits. Generic code that works
+with character strings can simply use char_traits<>::length to
+determine the length of a null terminated string, safe in the
+knowledge that specialisations of char_traits will use the most
+appropriate method available to them.
+
+Type traits
+
+Class char_traits is
+a classic example of a collection of type specific properties
+wrapped up in a single class - what Nathan Myers termed a baggage
+class[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 value,
+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.
+
+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 type that is the result of the
+transformation. All of the type-traits classes are defined inside
+namespace boost; for
+brevity, namespace-qualification is omitted in most of the code
+samples given.
+
+Implementation
+
+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 value that is true only if T is void.
+
+template <typename T>
+struct is_void
+{ static const bool value = false; };
+
+template <>
+struct is_void<void>
+{ static const bool value = true; };
+
+Here we define a primary version of the template class is_void, 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:
+
+template <typename T>
+struct is_pointer
+{ static const bool value = false; };
+
+template <typename T>
+struct is_pointer<T*>
+{ static const bool value = true; };
+
+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:
+
+void foo(T);
+void foo(U);
+
+Then you can also write a partial specialisation of the form:
+
+template <typename T>
+class c{ /*details*/ };
+
+template <typename T>
+
+class c<U>{ /*details*/ };
+
+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.
+
+As a more complex example of partial specialisation consider
+the class remove_bounds<T>. This class defines a single
+typedef-member type 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:
+
+template <typename T>
+struct remove_bounds
+{ typedef T type; };
+
+template <typename T, std::size_t N>
+struct remove_bounds<T[N]>
+{ typedef T type; };
+
+The aim of remove_bounds is this: imagine a generic algorithm
+that is passed an array type as a template parameter, remove_bounds provides a means
+of determining the underlying type of the array. For example remove_bounds<int[4][5]>::type
+would evaluate to the type int[5]
. 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.
+
+Optimised copy
+
+As an example of how the type traits classes can be used,
+consider the standard library algorithm copy:
+
+template<typename Iter1, typename Iter2>
+Iter2 copy(Iter1 first, Iter1 last, Iter2 out);
+
+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 memcpy.
+In order to implement copy in terms of memcpy all of the following conditions
+need to be met:
+
+
+ - Both of the iterator types Iter1 and Iter2 must be
+ pointers.
+ - Both Iter1 and Iter2 must point to the same type -
+ excluding const
+ and volatile-qualifiers.
+ - The type pointed to by Iter1 must have a trivial
+ assignment operator.
+
+
+By trivial assignment operator we mean that the type is either
+a scalar type[3] or:
+
+
+ - The type has no user defined assignment operator.
+ - The type does not have any data members that are
+ references.
+ - All base classes, and all data member objects must have
+ trivial assignment operators.
+
+
+If all these conditions are met then a type can be copied
+using memcpy rather than
+using a compiler generated assignment operator. The type-traits
+library provides a class has_trivial_assign, such that has_trivial_assign<T>::value
+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 has_trivial_assign
+gives the wrong answer, it will give the "safe" wrong
+answer - that trivial assignment is not allowable.
+
+The code for an optimised version of copy that uses memcpy where appropriate is
+given in listing 1. The code begins by defining a template class copier,
+that takes a single Boolean template parameter, and has a static
+template member function do_copy
+which performs the generic version of copy
+(in other words the "slow but safe version"). Following
+that there is a specialisation for copier<true>:
+again this defines a static template member function do_copy, but this version uses
+memcpy to perform an "optimised" copy.
+
+In order to complete the implementation, what we need now is a
+version of copy, that calls copier<true>::do_copy
+if it is safe to use memcpy,
+and otherwise calls copier<false>::do_copy
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 copy and consider
+first the two typedefs v1_t and v2_t. These use std::iterator_traits<Iter1>::value_type
+to determine what type the two iterators point to, and then feed
+the result into another type-traits class remove_cv 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, copy
+declares an enumerated value can_opt 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 copier. The
+value of can_opt is computed by verifying that all of the
+following are true:
+
+
+ - first that the two iterators point to the same type by
+ using a type-traits class is_same.
+ - Then that both iterators are real pointers - using the
+ class is_pointer described above.
+ - Finally that the pointed-to types have a trivial
+ assignment operator using has_trivial_assign.
+
+
+Finally we can use the value of can_opt 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 memcpy, then it will do so,
+otherwise it will use a generic copy.
+
+Was it worth it?
+
+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.
+
+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:
+
+
+ - If you use the right algorithm for the job in the first
+ place then optimisation will not be required; in some
+ cases, memcpy is
+ the right algorithm.
+ - 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.
+
+
+Table 1: Time taken to copy 1000 elements using copy<const
+T*, T*> (times in micro-seconds)
+
+
+
+ Version
+ |
+ T
+ |
+ Time
+ |
+
+
+ "Optimised" copy |
+ char |
+ 0.99 |
+
+
+ Conventional copy |
+ char |
+ 8.07 |
+
+
+ "Optimised" copy |
+ int |
+ 2.52 |
+
+
+ Conventional copy |
+ int |
+ 8.02 |
+
+
+
+
+
+Pair of References
+
+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].
+
+First, let us examine the definition of "std::pair",
+omitting the comparision operators, default constructor, and
+template copy constructor for simplicity:
+
+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) { }
+};
+
+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:
+
+
+
+ Type of "T1" |
+ Type of parameter to
+ initializing constructor |
+
+
+ T
+ |
+ const T &
+ |
+
+
+ T &
+ |
+ T &
+ |
+
+
+ const T &
+ |
+ const T &
+ |
+
+
+
+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.
+
+
+
+ Type of "T1" |
+ Type of "const T1" |
+ Type of "add_reference<const
+ T1>::type" |
+
+
+ T
+ |
+ const T
+ |
+ const T &
+ |
+
+
+ T &
+ |
+ T & [8]
+ |
+ T &
+ |
+
+
+ const T &
+ |
+ const T &
+ |
+ const T &
+ |
+
+
+
+This allows us to build a primary template definition for
+"pair" that can contain non-reference types, reference
+types, and constant reference types:
+
+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) { }
+};
+
+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!
+
+This same extension could 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.
+
+Conclusion
+
+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.
+
+Acknowledgements
+
+The authors would like to thank Beman Dawes and Howard Hinnant
+for their helpful comments when preparing this article.
+
+References
+
+
+ - Nathan C. Myers, C++ Report, June 1995.
+ - 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.
+ - 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.
+ - This quote is from Donald Knuth, ACM Computing Surveys,
+ December 1974, pg 268.
+ - 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.
+ - 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".
+ - 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.
+ - 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.
+
+
+Listing 1
+
+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);
+}
+
+
+
+© Copyright John Maddock and Steve Cleary, 2000
+
+
diff --git a/development/include/boost/type_traits/ice.hpp b/development/include/boost/type_traits/ice.hpp
index 1cd5ceb..e2f72d5 100644
--- a/development/include/boost/type_traits/ice.hpp
+++ b/development/include/boost/type_traits/ice.hpp
@@ -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
+
diff --git a/development/include/boost/type_traits/same_traits.hpp b/development/include/boost/type_traits/same_traits.hpp
index 2a95465..e94f46a 100644
--- a/development/include/boost/type_traits/same_traits.hpp
+++ b/development/include/boost/type_traits/same_traits.hpp
@@ -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
+
diff --git a/development/include/boost/type_traits/transform_traits.hpp b/development/include/boost/type_traits/transform_traits.hpp
index b9d487c..e82f40f 100644
--- a/development/include/boost/type_traits/transform_traits.hpp
+++ b/development/include/boost/type_traits/transform_traits.hpp
@@ -175,6 +175,8 @@ public:
// include a bunch of full specialisations as a workaround:
//
#include
+#else
+#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x)
#endif
#endif // TRANSFORM_TRAITS_HPP
@@ -182,3 +184,4 @@ public:
+
diff --git a/development/include/boost/type_traits/transform_traits_spec.hpp b/development/include/boost/type_traits/transform_traits_spec.hpp
index 8d9560d..3d05115 100644
--- a/development/include/boost/type_traits/transform_traits_spec.hpp
+++ b/development/include/boost/type_traits/transform_traits_spec.hpp
@@ -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
#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
diff --git a/development/index.htm b/development/index.htm
index 7dc6d14..54b5b0e 100644
--- a/development/index.htm
+++ b/development/index.htm
@@ -5,7 +5,7 @@
content="text/html; charset=iso-8859-1">
-
+
Type Traits
@@ -471,8 +471,8 @@ relationship between two types:
8.5
Note that
- this template is currently broken with Borland's compiler,
- for constructor-based conversions. |
+ this template is currently broken with Borland's
+ compiler, for constructor-based conversions.
|
@@ -595,7 +595,64 @@ transformation to the template argument T:
-
+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
+
+
+ - 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
+ - Provide a user-level macro that will define such explicit
+ specializations for any user-defined type T.
+
+
+The first part guarantees the successful compilation of
+something like this:
+
+BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));
+
+...
+
+BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));
+
+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:
+
+struct my {};
+
+BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(my)
+
+BOOST_STATIC_ASSERT((is_same<my, remove_reference<my&>::type>::value));
+
+BOOST_STATIC_ASSERT((is_same<my, remove_const<my const>::type>::value));
+
+// etc.
+
+Note that the maco
+BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to
+nothing on those compilers that do support partial specialisation.
Compiler Support Information
@@ -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.
If there is no compiler support, to ensure that these
-traits always 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 not a POD.
+traits always 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 not a POD.
The following rules are automatically enforced:
diff --git a/examples/copy_example.cpp b/examples/copy_example.cpp
new file mode 100644
index 0000000..c20e27a
--- /dev/null
+++ b/examples/copy_example.cpp
@@ -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
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+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
+I2 copy_imp(I1 first, I1 last, I2 out)
+{
+ while(first != last)
+ {
+ *out = *first;
+ ++out;
+ ++first;
+ }
+ return out;
+}
+
+template
+struct copier
+{
+ template
+ static I2 do_copy(I1 first, I1 last, I2 out)
+ { return copy_imp(first, last, out); }
+};
+
+template <>
+struct copier
+{
+ template
+ 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
+inline I2 copy(I1 first, I1 last, I2 out)
+{
+ typedef typename boost::remove_cv::value_type>::type v1_t;
+ typedef typename boost::remove_cv::value_type>::type v2_t;
+ return detail::copier<
+ ::boost::type_traits::ice_and<
+ ::boost::is_same::value,
+ ::boost::is_pointer::value,
+ ::boost::is_pointer::value,
+ ::boost::has_trivial_assign::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
+inline I2 copy_(const I1& first, const I1& last, const I2& out)
+{
+ return detail::copier::do_copy(first, last, out);
+}
+
+template
+inline T* copy_(const T* first, const T* last, T* out)
+{
+ return detail::copier<
+ ::boost::has_trivial_assign::value
+ >::do_copy(first, last, out);
+}
+
+} // namespace detail
+
+template
+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: " << 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: " << result << endl;
+
+ // cache load:
+ opt::detail::copier::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::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: " << 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: " << result << endl;
+
+ // cache load:
+ opt::detail::copier::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::do_copy(cc_array, cc_array + array_size, c_array);
+ }
+ result = t.elapsed();
+ cout << "standard \"unoptimised\" copy: " << result << endl << endl;
+
+ return 0;
+}
+
+
+
+
+
+
diff --git a/examples/fill_example.cpp b/examples/fill_example.cpp
new file mode 100644
index 0000000..ce5f03e
--- /dev/null
+++ b/examples/fill_example.cpp
@@ -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
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#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
+void do_fill_(I first, I last, typename boost::call_traits::param_type val)
+{
+ while(first != last)
+ {
+ *first = val;
+ ++first;
+ }
+}
+
+template
+struct filler
+{
+ template
+ struct rebind
+ {
+ static void do_fill(I first, I last, typename boost::call_traits::param_type val)
+ { do_fill_(first, last, val); }
+ };
+};
+
+template <>
+struct filler
+{
+ template
+ struct rebind
+ {
+ static void do_fill(I first, I last, T val)
+ {
+ std::memset(first, val, last-first);
+ }
+ };
+};
+
+}
+
+template
+inline void fill(I first, I last, const T& val)
+{
+ typedef detail::filler<
+ ::boost::type_traits::ice_and<
+ ::boost::is_pointer::value,
+ ::boost::is_arithmetic::value,
+ (sizeof(T) == 1)
+ >::value> filler_t;
+ typedef typename filler_t:: template rebind 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: " << 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: " << 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: " << 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: " << result << endl << endl;
+
+ return 0;
+}
+
+
+
+
+
diff --git a/examples/iter_swap_example.cpp b/examples/iter_swap_example.cpp
new file mode 100644
index 0000000..898d0bd
--- /dev/null
+++ b/examples/iter_swap_example.cpp
@@ -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
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+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
+struct swapper
+{
+ template
+ static void do_swap(I one, I two)
+ {
+ typedef typename std::iterator_traits::value_type v_t;
+ v_t v = *one;
+ *one = *two;
+ *two = v;
+ }
+};
+
+#ifdef __GNUC__
+using std::swap;
+#endif
+
+template <>
+struct swapper
+{
+ template
+ static void do_swap(I one, I two)
+ {
+ using std::swap;
+ swap(*one, *two);
+ }
+};
+
+}
+
+template
+inline void iter_swap(I1 one, I2 two)
+{
+ typedef typename std::iterator_traits::reference r1_t;
+ typedef typename std::iterator_traits::reference r2_t;
+ detail::swapper<
+ ::boost::type_traits::ice_and<
+ ::boost::is_reference::value,
+ ::boost::is_reference::value,
+ ::boost::is_same::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 v1;
+ v1.push_back(0);
+ v1.push_back(1);
+ std::vector 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();
+}
+
+
diff --git a/examples/trivial_destructor_example.cpp b/examples/trivial_destructor_example.cpp
new file mode 100644
index 0000000..ff7d256
--- /dev/null
+++ b/examples/trivial_destructor_example.cpp
@@ -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
+
+#include
+#include
+
+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
+struct array_destroyer
+{
+ template
+ static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
+};
+
+template <>
+struct array_destroyer
+{
+ template
+ static void destroy_array(T*, T*){}
+};
+
+template
+void do_destroy_array(T* first, T* last)
+{
+ while(first != last)
+ {
+ first->~T();
+ ++first;
+ }
+}
+
+}; // namespace detail
+
+template
+inline void destroy_array(T* p1, T* p2)
+{
+ detail::array_destroyer::value>::destroy_array(p1, p2);
+}
+
+//
+// unoptimised versions of destroy_array:
+//
+template
+void destroy_array1(T* first, T* last)
+{
+ while(first != last)
+ {
+ first->~T();
+ ++first;
+ }
+}
+template
+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: " << 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(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(unoptimised#2): " << result << endl << endl;
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
diff --git a/include/boost/type_traits.hpp b/include/boost/type_traits.hpp
index b177a4e..04dcc68 100644
--- a/include/boost/type_traits.hpp
+++ b/include/boost/type_traits.hpp
@@ -10,14 +10,33 @@
#ifndef BOOST_TYPE_TRAITS_HPP
#define BOOST_TYPE_TRAITS_HPP
-#ifndef BOOST_CONFIG_HPP
-#include
-#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
-#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-#include
-#else
-#include
-#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
+
+
+
diff --git a/include/boost/type_traits/alignment_traits.hpp b/include/boost/type_traits/alignment_traits.hpp
new file mode 100644
index 0000000..7de0c30
--- /dev/null
+++ b/include/boost/type_traits/alignment_traits.hpp
@@ -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
+#ifndef BOOST_ICE_TYPE_TRAITS_HPP
+#include
+#endif
+
+namespace boost{
+//
+// get the alignment of some arbitrary type:
+namespace detail{
+
+template
+struct alignment_of_hack
+{
+ char c;
+ T t;
+ alignment_of_hack();
+};
+
+template
+struct alignment_logic
+{
+ BOOST_DECL_MC(std::size_t, value, A < S ? A : S);
+};
+
+} // namespace detail
+
+template
+struct alignment_of
+{
+ BOOST_DECL_MC(std::size_t, value,
+ (::boost::detail::alignment_logic<
+ sizeof(detail::alignment_of_hack) - 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
+struct alignment_of
+{
+public:
+ BOOST_DECL_MC(std::size_t, value, alignment_of::value);
+};
+#endif
+//
+// void has to be treated specially:
+template <>
+struct alignment_of
+{ BOOST_DECL_MC(std::size_t, value, 0); };
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <>
+struct alignment_of
+{ BOOST_DECL_MC(std::size_t, value, 0); };
+template <>
+struct alignment_of
+{ BOOST_DECL_MC(std::size_t, value, 0); };
+template <>
+struct alignment_of
+{ BOOST_DECL_MC(std::size_t, value, 0); };
+#endif
+
+} // namespace boost
+
+#endif // ALIGNMENT_TYPE_TRAITS_HPP
+
+
diff --git a/include/boost/type_traits/arithmetic_traits.hpp b/include/boost/type_traits/arithmetic_traits.hpp
new file mode 100644
index 0000000..abd4cd9
--- /dev/null
+++ b/include/boost/type_traits/arithmetic_traits.hpp
@@ -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
+#endif
+#ifndef BOOST_FWD_TYPE_TRAITS_HPP
+#include
+#endif
+
+namespace boost{
+
+//* is a type T void - is_void
+template struct is_void{ BOOST_DECL_MC(bool, value, false); };
+template <> struct is_void{ BOOST_DECL_MC(bool, value, true); };
+
+//* is a type T an integral type described in the standard (3.9.1p3)
+template struct is_integral
+{ BOOST_DECL_MC(bool, value, false); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#ifndef BOOST_MSVC
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+
+#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
+template <> struct is_integral
+{ 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 struct is_float
+{ BOOST_DECL_MC(bool, value, false); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ 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
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_void
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_void
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+#ifndef BOOST_NO_CV_SPECIALIZATIONS
+// const-variations:
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#ifndef BOOST_MSVC
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+
+#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif // ULLONG_MAX
+#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif //__int64
+
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+
+// volatile-variations:
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#ifndef BOOST_MSVC
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+
+#ifdef ULLONG_MAX
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif // ULLONG_MAX
+#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif //__int64
+
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+
+// const-volatile-variations:
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#ifndef BOOST_MSVC
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+
+#ifdef ULLONG_MAX
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif // ULLONG_MAX
+#if defined(__BORLANDC__) || defined(_MSC_VER) && !defined(__MWERKS__)
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_integral
+{ BOOST_DECL_MC(bool, value, true); };
+#endif //__int64
+
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ BOOST_DECL_MC(bool, value, true); };
+template <> struct is_float
+{ 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
+struct is_arithmetic
+{
+ BOOST_DECL_MC(bool, value,
+ (::boost::type_traits::ice_or<
+ ::boost::is_integral::value,
+ ::boost::is_float::value
+ >::value));
+};
+
+//* is a type T a fundamental type described in the standard (3.9.1)
+template
+struct is_fundamental
+{
+ BOOST_DECL_MC(bool, value,
+ (::boost::type_traits::ice_or<
+ ::boost::is_arithmetic::value,
+ ::boost::is_void::value
+ >::value));
+};
+
+} // namespace boost
+
+#endif
+
+
+
+
+
diff --git a/include/boost/type_traits/composite_traits.hpp b/include/boost/type_traits/composite_traits.hpp
new file mode 100644
index 0000000..fd7b62d
--- /dev/null
+++ b/include/boost/type_traits/composite_traits.hpp
@@ -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:
+// 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
+#endif
+#ifndef BOOST_FWD_TYPE_TRAITS_HPP
+#include
+#endif
+#ifndef BOOST_CONVERSION_TYPE_TRAITS_HPP
+#include
+#endif
+#ifndef CV_TYPE_TRAITS_HPP
+#include
+#endif
+#ifndef ARITHMETIC_TYPE_TRAITS_HPP
+#include
+#endif
+
+namespace boost{
+
+/**********************************************
+ *
+ * is_array
+ *
+ **********************************************/
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template struct is_array
+{ BOOST_DECL_MC(bool, value, false); };
+template struct is_array
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_array
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_array
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_array
+{ 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
+ yes_type is_pointer_helper3(T (*)(void));
+ template
+ yes_type is_pointer_helper3(T (*)(A1));
+ template
+ yes_type is_pointer_helper3(T (*)(A1, A2));
+ template
+ 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
+ no_type is_array_helper(T*const volatile*, const volatile void*);
+ no_type is_array_helper(...);
+} // namespace detail
+template
+struct is_array
+{
+private:
+ static T t;
+public:
+ BOOST_DECL_MC(bool, value, (1 == sizeof(detail::is_array_helper(&t, t)))
+ & !is_reference::value
+ & !(1 == sizeof(detail::is_pointer_helper3(t))) );
+};
+template <>
+struct is_array
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <>
+struct is_array
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+template <>
+struct is_array
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+template <>
+struct is_array
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+#endif
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+/**********************************************
+ *
+ * is_pointer
+ *
+ **********************************************/
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+namespace detail{
+template struct is_pointer_helper
+{ BOOST_DECL_MC(bool, value, false); };
+template struct is_pointer_helper
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_pointer_helper
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_pointer_helper
+{ BOOST_DECL_MC(bool, value, true); };
+template struct is_pointer_helper
+{ BOOST_DECL_MC(bool, value, true); };
+} // namespace detail
+template struct is_pointer
+{ BOOST_DECL_MC(bool, value, (::boost::type_traits::ice_and< ::boost::detail::is_pointer_helper::value, !::boost::is_member_pointer::value>::value)); };
+#else
+template
+struct is_pointer
+{
+private:
+ static T t;
+public:
+ BOOST_DECL_MC(bool, value,
+ (::boost::type_traits::ice_and<
+ !::boost::is_reference::value,
+ !::boost::is_array::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
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <>
+struct is_pointer
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+template <>
+struct is_pointer
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+template <>
+struct is_pointer
+{
+ BOOST_DECL_MC(bool, value, false);
+};
+#endif
+#endif
+
+/**********************************************
+ *
+ * is_reference
+ *
+ **********************************************/
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template struct is_reference
+{ BOOST_DECL_MC(bool, value, false); };
+template