• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost enable_if library
2 
3 // Copyright 2003 (c) The Trustees of Indiana University.
4 
5 // Use, modification, and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 //    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
10 //             Jeremiah Willcock (jewillco at osl.iu.edu)
11 //             Andrew Lumsdaine (lums at osl.iu.edu)
12 
13 #include <boost/utility/enable_if.hpp>
14 #include <boost/type_traits/is_same.hpp>
15 #include <boost/core/lightweight_test.hpp>
16 
17 using boost::enable_if_c;
18 using boost::lazy_enable_if_c;
19 
20 // This class provides a reduced example of a traits class for
21 // computing the result of multiplying two types.  The member typedef
22 // 'type' in this traits class defines the return type of this
23 // operator.  The return type member is invalid unless both arguments
24 // for mult_traits are values that mult_traits expects (ints in this
25 // case).  This kind of situation may arise if a traits class only
26 // makes sense for some set of types, not all C++ types.
27 
28 template <class T> struct is_int {
29   BOOST_STATIC_CONSTANT(bool, value = (boost::is_same<T, int>::value));
30 };
31 
32 template <class T, class U>
33 struct mult_traits {
34   typedef typename T::does_not_exist type;
35 };
36 
37 template <>
38 struct mult_traits<int, int> {
39   typedef int type;
40 };
41 
42 
43 // Next, a forwarding function mult() is defined.  It is enabled only
44 // when both arguments are of type int.  The first version, using
45 // non-lazy enable_if_c does not work.
46 
47 #if 0
48 template <class T, class U>
49 typename enable_if_c<
50   is_int<T>::value && is_int<U>::value,
51   typename mult_traits<T, U>::type
52 >::type
53 mult(const T& x, const U& y) {return x * y;}
54 #endif
55 
56 // A correct version uses lazy_enable_if_c.
57 // This template removes compiler errors from invalid code used as an
58 // argument to enable_if_c.
59 
60 #if 1
61 template <class T, class U>
62 typename lazy_enable_if_c<
63   is_int<T>::value & is_int<U>::value,
64   mult_traits<T, U>
65 >::type
mult(const T & x,const U & y)66 mult(const T& x, const U& y) {return x * y;}
67 #endif
68 
mult(int i,double d)69 double mult(int i, double d) { return (double)i * d; }
70 
main()71 int main()
72 {
73 
74 
75   BOOST_TEST(mult(1, 2) == 2);
76 
77   BOOST_TEST(mult(1, 3.0) == 3.0);
78 
79   return boost::report_errors();
80 }
81 
82