// // Copyright 2003 © The Trustees of Indiana University. All rights // reserved. // // See the file enable_if_LICENSE for licensing conditions. // // Authors: Jaakko Järvi (jajarvi@osl.iu.edu) // Jeremiah Willcock (jewillco@osl.iu.edu) // Andrew Lumsdaine (lums@osl.iu.edu) // #include #include #include using boost::enable_if_c; using boost::lazy_enable_if_c; using boost::is_arithmetic; // This class provides a reduced example of a traits class for computing // the result of multiplying two types. The exists constant is true when a // multiplication operator exists between two types, and the type member is // defined to the return type of this operator. The return type member is // not defined when a multiplication operator does not exist. template struct mult_traits { BOOST_STATIC_CONSTANT(bool, exists = false); }; template <> struct mult_traits { BOOST_STATIC_CONSTANT(bool, exists = true); typedef int type; }; template <> struct mult_traits { BOOST_STATIC_CONSTANT(bool, exists = true); typedef double type; }; // Next, a forwarding function mult() is defined. It is enabled only when // mult_traits::exists is true. The first version, using normal // enable_if_c, works with only some compilers (it does not work in g++): #if 0 template typename enable_if_c< mult_traits::exists, typename mult_traits::type>::type mult(const T& x, const U& y) {return x * y;} #endif // An improved version that works with more compilers uses lazy_enable_if_c. // This template removes compiler errors from invalid code used as an // argument to enable_if_c. template typename lazy_enable_if_c< mult_traits::exists, mult_traits >::type mult(const T& x, const U& y) {return x * y;} int test_main(int, char*[]) { BOOST_TEST(mult(1, 2) == 2); BOOST_TEST(mult(1.0, 3.0) == 3.0); return 0; }