mirror of
https://github.com/boostorg/core.git
synced 2025-07-31 13:27:29 +02:00
Introduces enable_if_type
enable_if_type allow to perform SFINAE check on the existence of a dependent type. It has been used here and there in various boost library but it's useful enough to warrant an autonomous existence.
This commit is contained in:
@@ -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
|
again, the second argument to `enable_if` is not needed; the
|
||||||
default (`void`) is the correct value.
|
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 T, class Enable = void>
|
||||||
|
class value_type_from
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class value_type_from<T, typename enable_if_type<typename T::value_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::value_type type;
|
||||||
|
};
|
||||||
|
``
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section Overlapping enabler conditions]
|
[section Overlapping enabler conditions]
|
||||||
|
@@ -23,6 +23,11 @@
|
|||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
template<typename T, typename R=void>
|
||||||
|
struct enable_if_type
|
||||||
|
{
|
||||||
|
typedef R type;
|
||||||
|
};
|
||||||
|
|
||||||
template <bool B, class T = void>
|
template <bool B, class T = void>
|
||||||
struct enable_if_c {
|
struct enable_if_c {
|
||||||
@@ -80,6 +85,10 @@ namespace boost {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct enable_if_does_not_work_on_this_compiler;
|
struct enable_if_does_not_work_on_this_compiler;
|
||||||
|
|
||||||
|
template<typename T, typename R=void>
|
||||||
|
struct enable_if_type : enable_if_does_not_work_on_this_compiler<T>
|
||||||
|
{ };
|
||||||
|
|
||||||
template <bool B, class T = detail::enable_if_default_T>
|
template <bool B, class T = detail::enable_if_default_T>
|
||||||
struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
|
||||||
{ };
|
{ };
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <boost/type_traits/is_arithmetic.hpp>
|
#include <boost/type_traits/is_arithmetic.hpp>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
using boost::enable_if_type;
|
||||||
using boost::enable_if_c;
|
using boost::enable_if_c;
|
||||||
using boost::disable_if_c;
|
using boost::disable_if_c;
|
||||||
using boost::enable_if;
|
using boost::enable_if;
|
||||||
@@ -46,9 +47,28 @@ struct tester2<T, typename disable_if<is_arithmetic<T> >::type> {
|
|||||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T, class Enable = void>
|
||||||
|
class tester3
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class tester3<T, typename enable_if_type<typename T::value_type>::type>
|
||||||
|
{
|
||||||
|
typedef typename T::value_type type;
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sample_value_type
|
||||||
|
{
|
||||||
|
typedef float***& value_type;
|
||||||
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
BOOST_TEST(tester<int>::value);
|
BOOST_TEST(tester<int>::value);
|
||||||
BOOST_TEST(tester<double>::value);
|
BOOST_TEST(tester<double>::value);
|
||||||
|
|
||||||
@@ -61,6 +81,9 @@ int main()
|
|||||||
BOOST_TEST(!tester2<char*>::value);
|
BOOST_TEST(!tester2<char*>::value);
|
||||||
BOOST_TEST(!tester2<void*>::value);
|
BOOST_TEST(!tester2<void*>::value);
|
||||||
|
|
||||||
|
BOOST_TEST(!tester3<char*>::value);
|
||||||
|
BOOST_TEST(tester3<sample_value_type>::value);
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user