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
+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;
+}
+
+
+
+
+
+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.
+
+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; }
+
+
+
+
++ +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.
+
+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.
+
+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.
+
+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.
+
+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.+ +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: +
+
+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);
+
+
+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).
+This document was translated from LATEX by +HEVEA. ++ + 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