diff --git a/doc/enable_if.qbk b/doc/enable_if.qbk index 7a2af6c..3098f82 100644 --- a/doc/enable_if.qbk +++ b/doc/enable_if.qbk @@ -304,6 +304,26 @@ 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. +The `enable_if_type` template is usable this scenario but instead of +using a type traits to enable or disable a specialization, it use a +SFINAE context to check for the existence of a dependent type inside +its parameter. For example, the following structure extracts a dependent +`value_type` from T if and only if `T::value_type` exists. + +`` +template +class value_type_from +{ + typedef T type; +}; + +template +class value_type_from::type> +{ + typedef typename T::value_type type; +}; +`` + [endsect] [section Overlapping enabler conditions] diff --git a/include/boost/core/enable_if.hpp b/include/boost/core/enable_if.hpp index a3302b1..b5c1a98 100644 --- a/include/boost/core/enable_if.hpp +++ b/include/boost/core/enable_if.hpp @@ -23,6 +23,11 @@ namespace boost { + template + struct enable_if_type + { + typedef R type; + }; template struct enable_if_c { @@ -80,6 +85,10 @@ namespace boost { template struct enable_if_does_not_work_on_this_compiler; + template + struct enable_if_type : enable_if_does_not_work_on_this_compiler + { }; + template struct enable_if_c : enable_if_does_not_work_on_this_compiler { }; diff --git a/test/eif_partial_specializations.cpp b/test/eif_partial_specializations.cpp index a023f53..4817a88 100644 --- a/test/eif_partial_specializations.cpp +++ b/test/eif_partial_specializations.cpp @@ -14,6 +14,7 @@ #include #include +using boost::enable_if_type; using boost::enable_if_c; using boost::disable_if_c; using boost::enable_if; @@ -46,9 +47,28 @@ struct tester2 >::type> { BOOST_STATIC_CONSTANT(bool, value = false); }; +template +class tester3 +{ + typedef T type; + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +class tester3::type> +{ + typedef typename T::value_type type; + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +struct sample_value_type +{ + typedef float***& value_type; +}; + int main() { - + BOOST_TEST(tester::value); BOOST_TEST(tester::value); @@ -61,6 +81,9 @@ int main() BOOST_TEST(!tester2::value); BOOST_TEST(!tester2::value); + BOOST_TEST(!tester3::value); + BOOST_TEST(tester3::value); + return boost::report_errors(); }