File: sfinae.cpp

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (104 lines) | stat: -rw-r--r-- 2,694 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright David Abrahams, Daniel Wallin 2003. 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

#include <boost/parameter.hpp>
#include <boost/parameter/match.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
#include <boost/type_traits/is_convertible.hpp>

#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif 

namespace test
{
  BOOST_PARAMETER_KEYWORD(keywords,name)
  BOOST_PARAMETER_KEYWORD(keywords,value)
  
  using namespace boost::parameter;

  struct f_parameters
    : parameters<
          optional<
              keywords::name
            , boost::is_convertible<boost::mpl::_, std::string>
          >
        , optional<
              keywords::value
            , boost::is_convertible<boost::mpl::_, float>
          >
      >
  {};

  // The use of assert_equal_string is just a nasty workaround for a
  // vc++ 6 ICE.
  void assert_equal_string(std::string x, std::string y)
  {
        BOOST_TEST(x == y);
  }
  
  template<class P>
  void f_impl(P const& p)
  {
      float v = p[value | 3.f];
      BOOST_TEST(v == 3.f);
      assert_equal_string(p[name | "bar"], "foo");
  }

  void f()
  {
      f_impl(f_parameters()());
  }

  template<class A0>
  void f(
      A0 const& a0
    , BOOST_PARAMETER_MATCH(f_parameters, (A0), args))
  {
      f_impl(args(a0));
  }

  template<class A0, class A1>
  void f(
      A0 const& a0, A1 const& a1
    , BOOST_PARAMETER_MATCH(f_parameters,(A0)(A1), args))
  {
      f_impl(args(a0, a1));
  }

#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
  // On compilers that actually support SFINAE, add another overload
  // that is an equally good match and can only be in the overload set
  // when the others are not.  This tests that the SFINAE is actually
  // working.  On all other compilers we're just checking that
  // everything about SFINAE-enabled code will work, except of course
  // the SFINAE.
  template<class A0, class A1>
  typename boost::enable_if<boost::is_same<int,A0>, int>::type
  f(A0 const& a0, A1 const& a1)
  {
      return 0;
  }
#endif 
} // namespace test

int main()
{
    using test::name;
    using test::value;    
    using test::f;

    f("foo");
    f("foo", 3.f);
    f(value = 3.f, name = "foo");

#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
    BOOST_TEST(f(3, 4) == 0);
#endif
    return boost::report_errors();
}