diff --git a/enable_if.html b/enable_if.html
new file mode 100644
index 0000000..349189e
--- /dev/null
+++ b/enable_if.html
@@ -0,0 +1,417 @@
+
+
+
enable_if
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
enable_if
+
+
+Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.
+
+
+
+1 Introduction
+
+
+The enable_if family of templates is a set of tools to allow a function template or a class template specialization
+to include or exclude itself from a set of matching functions or specializations
+based on properties of its template arguments.
+For example, one can define function templates that
+are only enabled for, and thus only match, an arbitrary set of types
+defined by a traits class. The enable_if templates can also be
+applied to enable class template specializations. Applications of
+enable_if are discussed in length
+in [1] and [2].
+
+
+
+1.1 Synopsis
+
+
+
+namespace boost {
+ template <class Cond, class T = void> struct enable_if;
+ template <class Cond, class T = void> struct disable_if;
+ template <class Cond, class T> struct lazy_enable_if;
+ template <class Cond, class T> struct lazy_disable_if;
+
+ template <bool B, class T = void> struct enable_if_c;
+ template <bool B, class T = void> struct disable_if_c;
+ template <bool B, class T> struct lazy_enable_if_c;
+ template <bool B, class T> struct lazy_disable_if_c;
+}
+
+
+
+1.2 Background
+
+
+Sensible operation of template function overloading in C++ relies
+on the SFINAE (substitution-failure-is-not-an-error)
+principle [3]: if an invalid argument
+or return type is formed during the instantiation of a function
+template, the instantiation is removed from the overload resolution
+set instead of causing a compilation error. The following example,
+taken from [1],
+demonstrates why this is important:
+
+
+int negate(int i) { return -i; }
+
+template <class F>
+typename F::result_type negate(const F& f) { return -f(); }
+
+
+Suppose the compiler encounters the call negate(1). The first
+definition is obviously a better match, but the compiler must
+nevertheless consider (and instantiate the prototypes) of both
+definitions to find this out. Instantiating the latter definition with
+F as int would result in:
+
+
+int::result_type negate(const int&);
+
+
+where the return type is invalid. If this was an error, adding an unrelated function template
+(that was never called) could break otherwise valid code.
+Due to the SFINAE principle the above example is not, however, erroneous.
+The latter definition of negate is simply removed from the overload resolution set.
+
+The enable_if templates are tools for controlled creation of the SFINAE
+conditions.
+
+
+
+2 The enable_if templates
+
+
+The names of the enable_if templates have three parts: an optional lazy_ tag,
+either enable_if or disable_if, and an optional _c tag.
+All eight combinations of these parts are supported.
+The meaning of the lazy_ tag is described in Section 3.3.
+The second part of the name indicates whether a true condition argument should
+enable or disable the current overload.
+The third part of the name indicates whether the condition argument is a bool value
+(_c suffix), or a type containing a static bool constant named value (no suffix).
+The latter version interoperates with Boost.MPL.
+
+The definitions of enable_if_c and enable_if are as follows (we use enable_if templates
+unqualified but they are in the boost namespace).
+
+
+template <bool B, class T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+template <class Cond, class T = void>
+struct enable_if : public enable_if_c<Cond::value, T> {};
+
+
+An instantiation of the enable_if_c template with the parameter
+B as true contains a member type type, defined
+to be T. If B is
+false, no such member is defined. Thus
+enable_if_c<B, T>::type is either a valid or an invalid type
+expression, depending on the value of B.
+When valid, enable_if_c<B, T>::type equals T.
+The enable_if_c template can thus be used for controlling when functions are considered for
+overload resolution and when they are not.
+For example, the following function is defined for all arithmetic types (according to the
+classification of the Boost type_traits library):
+
+
+template <class T>
+typename enable_if_c<boost::is_arithmetic<T>::value, T>::type
+foo(T t) { return t; }
+
+
+The disable_if_c template is provided as well, and has the
+same functionality as enable_if_c except for the negated condition. The following
+function is enabled for all non-arithmetic types.
+
+
+template <class T>
+typename disable_if_c<boost::is_arithmetic<T>::value, T>::type
+bar(T t) { return t; }
+
+
+For easier syntax in some cases and interoperation with Boost.MPL we provide versions of
+the enable_if templates taking any type with a bool member constant named
+value as the condition argument.
+The MPL bool_, and_, or_, and not_ templates are likely to be
+useful for creating such types. Also, the traits classes in the Boost.Type_traits library
+follow this convention.
+For example, the above example function foo can be alternatively written as:
+
+
+template <class T>
+typename enable_if<boost::is_arithmetic<T>, T>::type
+foo(T t) { return t; }
+
+
+
+
+3 Using enable_if
+
+
+The enable_if templates are defined in
+boost/utility/enable_if.hpp, which is included by boost/utility.hpp.
+
+The enable_if template can be used either as the return type, or as an
+extra argument. For example, the foo function in the previous section could also be written
+as:
+
+
+template <class T>
+T foo(T t, typename enable_if<boost::is_arithmetic<T> >::type* dummy = 0);
+
+
Hence, an extra parameter of type void* is added, but it is given
+a default value to keep the parameter hidden from client code.
+Note that the second template argument was not given to enable_if, as the default
+void gives the desired behavior.
+
+Whether to write the enabler as an argument or within the return type is
+largely a matter of taste, but for certain functions, only one
+alternative is possible:
+-
+Operators have a fixed number of arguments, thus enable_if must be used in the return type.
+
- Constructors and destructors do not have a return type; an extra argument is the only option.
+
- There does not seem to be a way to specify an enabler for a conversion operator. Converting constructors,
+however, can have enablers as extra default arguments.
+
+
+
+3.1 Enabling template class specializations
+
+
+Class template specializations can be enabled or disabled with enable_if.
+One extra template parameter needs to be added for the enabler expressions.
+This parameter has the default value void.
+For example:
+
+
+template <class T, class Enable = void>
+class A { ... };
+
+template <class T>
+class A<T, typename enable_if<is_integral<T> >::type> { ... };
+
+template <class T>
+class A<T, typename enable_if<is_float<T> >::type> { ... };
+
+
Instantiating A with any integral type matches the first specialization,
+whereas any floating point type matches the second one. All other types
+match the primary template.
+The condition can be any compile-time boolean expression that depends on the
+template arguments of the class.
+Note that again, the second argument to enable_if is not needed; the default (void)
+is the correct value.
+
+
+
+3.2 Overlapping enabler conditions
+
+
+Once the compiler has examined the enabling conditions and included the
+function into the overload resolution set, normal C++ overload resolution
+rules are used to select the best matching function.
+In particular, there is no ordering between enabling conditions.
+Function templates with enabling conditions that are not mutually exclusive can
+lead to ambiguities. For example:
+
+
+template <class T>
+typename enable_if<boost::is_integral<T>, void>::type
+foo(T t) {}
+
+template <class T>
+typename enable_if<boost::is_arithmetic<T>, void>::type
+foo(T t) {}
+
+
+All integral types are also arithmetic. Therefore, say, for the call foo(1),
+both conditions are true and both functions are thus in the overload resolution set.
+They are both equally good matches and thus ambiguous.
+Of course, more than one enabling condition can be simultaneously true as long as
+other arguments disambiguate the functions.
+
+The above discussion applies to using enable_if in class template
+partial specializations as well.
+
+
+
+3.3 Lazy enable_if
+
+
+In some cases it is necessary to avoid instantiating part of a
+function signature unless an enabling condition is true. For example:
+
+
+template <class T, class U> class mult_traits;
+
+template <class T, class U>
+typename enable_if<is_multipliable<T, U>, typename mult_traits<T, U>::type>::type
+operator*(const T& t, const U& u) { ... }
+
+
Assume the class template mult_traits is a traits class defining
+the resulting type of a multiplication operator. The is_multipliable traits
+class specifies for which types to enable the operator. Whenever
+is_multipliable<A, B>::value is true for some types A and B,
+then mult_traits<A, B>::type is defined.
+
+Now, trying to invoke (some other overload) of operator* with, say, operand types C and D
+for which is_multipliable<C, D>::value is false
+and mult_traits<C, D>::type is not defined is an error on some compilers.
+The SFINAE principle is not applied because
+the invalid type occurs as an argument to another template. The lazy_enable_if
+and lazy_disable_if templates (and their _c versions) can be used in such
+situations:
+
+
+template<class T, class U>
+typename lazy_enable_if<is_multipliable<T, U>, mult_traits<T, U> >::type
+operator*(const T& t, const U& u) { ... }
+
+
The second argument of lazy_enable_if must be a class type
+that defines a nested type named type whenever the first
+parameter (the condition) is true.
+
+
+
+Note
+
+Referring to one member type or static constant in a traits class
+causes all of the members (type and static constant) of that
+specialization to be instantiated. Therefore, if your traits classes
+can sometimes contain invalid types, you should use two distinct
+templates for describing the conditions and the type mappings. In the
+above example, is_multipliable<T, U>::value defines when
+mult_traits<T, U>::type is valid.
+
+
+
+3.4 Compiler workarounds
+
+
+Some compilers flag functions as ambiguous if the only distinguishing factor is a different
+condition in an enabler (even though the functions could never be ambiguous). For example,
+some compilers (e.g. GCC 3.2) diagnose the following two functions as ambiguous:
+
+
+template <class T>
+typename enable_if<boost::is_arithmetic<T>, T>::type
+foo(T t);
+
+template <class T>
+typename disable_if<boost::is_arithmetic<T>, T>::type
+foo(T t);
+
+
Two workarounds can be applied:
+-
+Use an extra dummy parameter which disambiguates the functions. Use a default value for
+it to hide the parameter from the caller. For example:
+
+
+template <class T> struct dummy { dummy(int) {} };
+
+template <class T>
+typename enable_if<boost::is_arithmetic<T>, T>::type
+foo(T t, dummy<0> = 0);
+
+template <class T>
+typename disable_if<boost::is_arithmetic<T>, T>::type
+foo(T t, dummy<1> = 0);
+
+
+ - Define the functions in different namespaces and bring them into a common
+namespace with using declarations:
+
+
+namespace A {
+ template <class T>
+ typename enable_if<boost::is_arithmetic<T>, T>::type
+ foo(T t);
+}
+
+namespace B {
+ template <class T>
+ typename disable_if<boost::is_arithmetic<T>, T>::type
+ foo(T t);
+}
+
+using A::foo;
+using B::foo;
+
+
+Note that the second workaround above cannot be used for member
+templates. On the other hand, operators do not accept extra arguments,
+which makes the first workaround unusable. As the net effect,
+neither of the workarounds are of assistance for templated operators that
+need to be defined as member functions (assignment and
+subscript operators).
+
+
+
+4 Acknowledgements
+
+We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard
+Smith whose findings have influenced the library.
+
+
+
+References
+- [1]
-
+Jaakko Järvi, Jeremiah Willcock, Howard Hinnant, and Andrew Lumsdaine.
+Function overloading based on arbitrary properties of types.
+C/C++ Users Journal, 21(6):25--32, June 2003.
+
+ - [2]
-
+Jaakko Järvi, Jeremiah Willcock, and Andrew Lumsdaine.
+Concept-controlled polymorphism.
+In Frank Pfennig and Yannis Smaragdakis, editors, Generative
+ Programming and Component Engineering, volume 2830 of LNCS, pages
+ 228--244. Springer Verlag, September 2003.
+
+ - [3]
-
+David Vandevoorde and Nicolai M. Josuttis.
+C++ Templates: The Complete Guide.
+Addison-Wesley, 2002.
+
+
+
+
+
+
+
+Contributed by:
+Jaakko Järvi, Jeremiah Willcock and Andrew Lumsdaine
+{jajarvi|jewillco|lums}@osl.iu.edu
+Indiana University
+Open Systems Lab
+
+
+
+
+This document was translated from LATEX by
+HEVEA.
+
+
+
diff --git a/enable_if_constructors.cpp b/enable_if_constructors.cpp
new file mode 100644
index 0000000..0dabd01
--- /dev/null
+++ b/enable_if_constructors.cpp
@@ -0,0 +1,62 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+
+#include
+#include
+
+using boost::enable_if;
+using boost::disable_if;
+using boost::is_arithmetic;
+
+struct container {
+ bool my_value;
+
+ template
+ container(const T&, const typename enable_if, T>::type * = 0):
+ my_value(true) {}
+
+ template
+ container(const T&, const typename disable_if, T>::type * = 0):
+ my_value(false) {}
+};
+
+// example from Howard Hinnant (tests enable_if template members of a templated class)
+template
+struct xstring
+{
+ template
+ xstring(It begin, It end, typename
+ disable_if >::type* = 0)
+ : data(end-begin) {}
+
+ int data;
+};
+
+
+int test_main(int, char*[])
+{
+
+ BOOST_CHECK(container(1).my_value);
+ BOOST_CHECK(container(1.0).my_value);
+
+ BOOST_CHECK(!container("1").my_value);
+ BOOST_CHECK(!container(static_cast(0)).my_value);
+
+ char sa[] = "123456";
+ BOOST_CHECK(xstring(sa, sa+6).data == 6);
+
+
+ return 0;
+}
+
diff --git a/enable_if_dummy_arg_disambiguation.cpp b/enable_if_dummy_arg_disambiguation.cpp
new file mode 100644
index 0000000..bb9f733
--- /dev/null
+++ b/enable_if_dummy_arg_disambiguation.cpp
@@ -0,0 +1,46 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+
+#include
+#include
+
+using boost::enable_if;
+using boost::disable_if;
+using boost::is_arithmetic;
+
+template struct dummy {
+ dummy(int) {};
+};
+
+template
+typename enable_if, bool>::type
+arithmetic_object(T t, dummy<0> = 0) { return true; }
+
+template
+typename disable_if, bool>::type
+arithmetic_object(T t, dummy<1> = 0) { return false; }
+
+
+int test_main(int, char*[])
+{
+
+ BOOST_CHECK(arithmetic_object(1));
+ BOOST_CHECK(arithmetic_object(1.0));
+
+ BOOST_CHECK(!arithmetic_object("1"));
+ BOOST_CHECK(!arithmetic_object(static_cast(0)));
+
+ return 0;
+}
+
diff --git a/enable_if_lazy.cpp b/enable_if_lazy.cpp
new file mode 100644
index 0000000..6e7d650
--- /dev/null
+++ b/enable_if_lazy.cpp
@@ -0,0 +1,82 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+
+#include
+#include
+
+using boost::enable_if_c;
+using boost::lazy_enable_if_c;
+
+// This class provides a reduced example of a traits class for
+// computing the result of multiplying two types. The member typedef
+// 'type' in this traits class defines the return type of this
+// operator. The return type member is invalid unless both arguments
+// for mult_traits are values that mult_traits expects (ints in this
+// case). This kind of situation may arise if a traits class only
+// makes sense for some set of types, not all C++ types.
+
+template struct is_int {
+ BOOST_STATIC_CONSTANT(bool, value = (boost::is_same::value));
+};
+
+template
+struct mult_traits {
+ typedef typename T::does_not_exist type;
+};
+
+template <>
+struct mult_traits {
+ typedef int type;
+};
+
+
+// Next, a forwarding function mult() is defined. It is enabled only
+// when both arguments are of type int. The first version, using
+// non-lazy enable_if_c does not work.
+
+#if 0
+template
+typename enable_if_c<
+ is_int::value && is_int::value,
+ typename mult_traits::type
+>::type
+mult(const T& x, const U& y) {return x * y;}
+#endif
+
+// A correct version uses lazy_enable_if_c.
+// This template removes compiler errors from invalid code used as an
+// argument to enable_if_c.
+
+#if 1
+template
+typename lazy_enable_if_c<
+ is_int::value && is_int::value,
+ mult_traits
+>::type
+mult(const T& x, const U& y) {return x * y;}
+#endif
+
+double mult(int i, double d) { return (double)i * d; }
+
+int test_main(int, char*[])
+{
+
+
+ BOOST_CHECK(mult(1, 2) == 2);
+
+ BOOST_CHECK(mult(1, 3.0) == 3.0);
+
+ return 0;
+}
+
diff --git a/enable_if_lazy_test.cpp b/enable_if_lazy_test.cpp
new file mode 100644
index 0000000..672c7b4
--- /dev/null
+++ b/enable_if_lazy_test.cpp
@@ -0,0 +1,100 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+// Testing all variations of lazy_enable_if.
+
+#include
+#include
+
+#include
+#include
+
+using boost::lazy_enable_if;
+using boost::lazy_disable_if;
+
+using boost::lazy_enable_if_c;
+using boost::lazy_disable_if_c;
+
+
+template
+struct is_int_or_double {
+ BOOST_STATIC_CONSTANT(bool,
+ value = (boost::is_same::value ||
+ boost::is_same::value));
+};
+
+template
+struct some_traits {
+ typedef typename T::does_not_exist type;
+};
+
+template <>
+struct some_traits {
+ typedef bool type;
+};
+
+template <>
+struct some_traits {
+ typedef bool type;
+};
+
+template
+struct make_bool {
+ typedef bool type;
+};
+
+template <>
+struct make_bool {};
+
+template <>
+struct make_bool {};
+
+namespace A {
+
+ template
+ typename lazy_enable_if, some_traits >::type
+ foo(T t) { return true; }
+
+ template
+ typename lazy_enable_if_c::value, some_traits >::type
+ foo2(T t) { return true; }
+}
+
+namespace B {
+ template
+ typename lazy_disable_if, make_bool >::type
+ foo(T t) { return false; }
+
+ template
+ typename lazy_disable_if_c::value, make_bool >::type
+ foo2(T t) { return false; }
+}
+
+int test_main(int, char*[])
+{
+ using namespace A;
+ using namespace B;
+ BOOST_CHECK(foo(1));
+ BOOST_CHECK(foo(1.0));
+
+ BOOST_CHECK(!foo("1"));
+ BOOST_CHECK(!foo(static_cast(0)));
+
+ BOOST_CHECK(foo2(1));
+ BOOST_CHECK(foo2(1.0));
+
+ BOOST_CHECK(!foo2("1"));
+ BOOST_CHECK(!foo2(static_cast(0)));
+
+ return 0;
+}
+
diff --git a/enable_if_member_templates.cpp b/enable_if_member_templates.cpp
new file mode 100644
index 0000000..23dd173
--- /dev/null
+++ b/enable_if_member_templates.cpp
@@ -0,0 +1,43 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+
+#include
+#include
+
+using boost::enable_if;
+using boost::disable_if;
+using boost::is_arithmetic;
+
+struct container {
+ template
+ typename enable_if, bool>::type
+ arithmetic_object(const T&, const int* /* disambiguate */ = 0) {return true;}
+
+ template
+ typename disable_if, bool>::type
+ arithmetic_object(const T&) {return false;}
+};
+
+int test_main(int, char*[])
+{
+
+ BOOST_CHECK(container().arithmetic_object(1));
+ BOOST_CHECK(container().arithmetic_object(1.0));
+
+ BOOST_CHECK(!container().arithmetic_object("1"));
+ BOOST_CHECK(!container().arithmetic_object(static_cast(0)));
+
+ return 0;
+}
+
diff --git a/enable_if_namespace_disambiguation.cpp b/enable_if_namespace_disambiguation.cpp
new file mode 100644
index 0000000..90a98a1
--- /dev/null
+++ b/enable_if_namespace_disambiguation.cpp
@@ -0,0 +1,47 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+#include
+
+#include
+#include
+
+using boost::enable_if;
+using boost::mpl::not_;
+using boost::is_arithmetic;
+
+namespace A {
+ template
+ typename enable_if, bool>::type
+ arithmetic_object(T t) { return true; }
+}
+
+namespace B {
+ template
+ typename enable_if >, bool>::type
+ arithmetic_object(T t) { return false; }
+}
+
+int test_main(int, char*[])
+{
+ using namespace A;
+ using namespace B;
+ BOOST_CHECK(arithmetic_object(1));
+ BOOST_CHECK(arithmetic_object(1.0));
+
+ BOOST_CHECK(!arithmetic_object("1"));
+ BOOST_CHECK(!arithmetic_object(static_cast(0)));
+
+ return 0;
+}
+
diff --git a/enable_if_no_disambiguation.cpp b/enable_if_no_disambiguation.cpp
new file mode 100644
index 0000000..f4936e8
--- /dev/null
+++ b/enable_if_no_disambiguation.cpp
@@ -0,0 +1,43 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+#include
+
+#include
+#include
+
+using boost::mpl::not_;
+using boost::enable_if;
+using boost::is_arithmetic;
+
+template
+typename enable_if, bool>::type
+arithmetic_object(T t) { return true; }
+
+template
+typename enable_if >, bool>::type
+arithmetic_object(T t) { return false; }
+
+
+int test_main(int, char*[])
+{
+
+ BOOST_CHECK(arithmetic_object(1));
+ BOOST_CHECK(arithmetic_object(1.0));
+
+ BOOST_CHECK(!arithmetic_object("1"));
+ BOOST_CHECK(!arithmetic_object(static_cast(0)));
+
+ return 0;
+}
+
diff --git a/enable_if_partial_specializations.cpp b/enable_if_partial_specializations.cpp
new file mode 100644
index 0000000..3dce799
--- /dev/null
+++ b/enable_if_partial_specializations.cpp
@@ -0,0 +1,67 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+#include
+
+#include
+#include
+
+using boost::enable_if_c;
+using boost::disable_if_c;
+using boost::enable_if;
+using boost::disable_if;
+using boost::is_arithmetic;
+
+template
+struct tester;
+
+template
+struct tester::value>::type> {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template
+struct tester::value>::type> {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template
+struct tester2;
+
+template
+struct tester2 >::type> {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template
+struct tester2 >::type> {
+ BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+int test_main(int, char*[])
+{
+
+ BOOST_CHECK(tester::value);
+ BOOST_CHECK(tester::value);
+
+ BOOST_CHECK(!tester::value);
+ BOOST_CHECK(!tester::value);
+
+ BOOST_CHECK(tester2::value);
+ BOOST_CHECK(tester2::value);
+
+ BOOST_CHECK(!tester2::value);
+ BOOST_CHECK(!tester2::value);
+
+ return 0;
+}
+
diff --git a/include/boost/utility/enable_if.hpp b/include/boost/utility/enable_if.hpp
new file mode 100644
index 0000000..c1f217d
--- /dev/null
+++ b/include/boost/utility/enable_if.hpp
@@ -0,0 +1,69 @@
+// Boost enable_if library
+
+// Copyright 2003 © The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+// Jeremiah Willcock (jewillco at osl.iu.edu)
+// Andrew Lumsdaine (lums at osl.iu.edu)
+
+
+#ifndef BOOST_UTILITY_ENABLE_IF_HPP
+#define BOOST_UTILITY_ENABLE_IF_HPP
+
+namespace boost
+{
+
+ template
+ struct enable_if_c {
+ typedef T type;
+ };
+
+ template
+ struct enable_if_c {};
+
+ template
+ struct enable_if : public enable_if_c {};
+
+ template
+ struct lazy_enable_if_c {
+ typedef typename T::type type;
+ };
+
+ template
+ struct lazy_enable_if_c {};
+
+ template
+ struct lazy_enable_if : public lazy_enable_if_c {};
+
+
+ template
+ struct disable_if_c {
+ typedef T type;
+ };
+
+ template
+ struct disable_if_c {};
+
+ template
+ struct disable_if : public disable_if_c {};
+
+ template
+ struct lazy_disable_if_c {
+ typedef typename T::type type;
+ };
+
+ template
+ struct lazy_disable_if_c {};
+
+ template
+ struct lazy_disable_if : public lazy_disable_if_c {};
+
+
+
+} // namespace boost
+
+#endif
diff --git a/index.html b/index.html
index f49e437..5a4731d 100644
--- a/index.html
+++ b/index.html
@@ -19,6 +19,7 @@
call_traits
checked_delete
compressed_pair
+ enable_if
iterator_adaptors
operators
throw_exception
diff --git a/test/Jamfile b/test/Jamfile
index 2199a8d..edf8902 100755
--- a/test/Jamfile
+++ b/test/Jamfile
@@ -30,4 +30,12 @@ test-suite utility
[ run ../compressed_pair_test.cpp ../../test/build/boost_test_exec_monitor : -u ]
[ run ../addressof_test.cpp ../../test/build/boost_test_exec_monitor ]
[ run ../ref_test.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_constructors.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_dummy_arg_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_lazy.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_lazy_test.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_member_templates.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_namespace_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_no_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_partial_specializations.cpp ../../test/build/boost_test_exec_monitor ]
;
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 41b9fb6..9c47e91 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -23,4 +23,12 @@ test-suite utility
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor : -u ]
[ run ../addressof_test.cpp ../../test/build//boost_test_exec_monitor ]
[ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor ]
+ [ run ../enable_if_constructors.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_dummy_arg_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_lazy.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_lazy_test.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_member_templates.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_namespace_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_no_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
+ [ run ../enable_if_partial_specializations.cpp ../../test/build/boost_test_exec_monitor ]
;