File: preprocessor_deduced.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 (171 lines) | stat: -rw-r--r-- 3,944 bytes parent folder | download | duplicates (8)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright Daniel Wallin 2006. 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/preprocessor.hpp>
#include <boost/parameter/name.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include "basics.hpp"

#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
#endif

namespace test {

namespace mpl = boost::mpl;

using mpl::_;
using boost::is_convertible;

BOOST_PARAMETER_NAME(expected)
BOOST_PARAMETER_NAME(x)
BOOST_PARAMETER_NAME(y)
BOOST_PARAMETER_NAME(z)

// Sun has problems with this syntax:
//
//   template1< r* ( template2<x> ) >
//
// Workaround: factor template2<x> into a separate typedef
typedef is_convertible<_, int> predicate1;
typedef is_convertible<_, std::string> predicate2;

#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))

BOOST_PARAMETER_FUNCTION((int), f, tag,
    (required
       (expected, *)
    )
    (deduced
       (required
          (x, *(predicate1))
          (y, *(predicate2))
       )
    )
)
#else
BOOST_PARAMETER_FUNCTION((int), f, tag,
    (required
       (expected, *)
    )
    (deduced
       (required
          (x, *(is_convertible<_, int>))
          (y, *(is_convertible<_, std::string>))
       )
    )
)
#endif 
{
    assert(equal(x, boost::tuples::get<0>(expected)));
    assert(equal(y, boost::tuples::get<1>(expected)));
    return 1;
}

struct X 
{
    X(int x = -1)
      : x(x)
    {}
    
    bool operator==(X const& other) const
    {
        return x == other.x;
    }
    
    int x;
};

typedef is_convertible<_, X> predicate3;  // SunPro workaround; see above

BOOST_PARAMETER_FUNCTION((int), g, tag,
    (required
      (expected, *)
    )
    (deduced
       (required
          (x, *(is_convertible<_, int>))
          (y, *(is_convertible<_, std::string>))
       )
       (optional
          (z, *(predicate3), X())
       )
    )
)
{
    assert(equal(x, boost::tuples::get<0>(expected)));
    assert(equal(y, boost::tuples::get<1>(expected)));
    assert(equal(z, boost::tuples::get<2>(expected)));
    return 1;
}

BOOST_PARAMETER_FUNCTION(
    (int), sfinae, tag,
    (deduced
      (required
        (x, *(predicate2))
      )
    )
)
{
    return 1;
}

#ifndef BOOST_NO_SFINAE
// 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>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
sfinae(A0 const& a0)
{
    return 0;
}
#endif

} // namespace test

using boost::make_tuple;

// make_tuple doesn't work with char arrays.
char const* str(char const* s)
{
    return s;
}

int main()
{
    using namespace test;

    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
    f(make_tuple(0, str("foo")), 0, "foo");
    f(make_tuple(0, str("foo")), "foo", 0);
    f(make_tuple(0, str("foo")), _y = "foo", 0);
    f(make_tuple(0, str("foo")), _x = 0, "foo");
    f(make_tuple(0, str("foo")), 0, _y = "foo");

    g(make_tuple(0, str("foo"), X()), _x = 0, _y = "foo");
    g(make_tuple(0, str("foo"), X()), 0, "foo");
    g(make_tuple(0, str("foo"), X()), "foo", 0);
    g(make_tuple(0, str("foo"), X()), _y = "foo", 0);   
    g(make_tuple(0, str("foo"), X()), _x = 0, "foo");
    g(make_tuple(0, str("foo"), X()), 0, _y = "foo");

    g(make_tuple(0, str("foo"), X(1)), 0, _y = "foo", X(1));
    g(make_tuple(0, str("foo"), X(1)), X(1), 0, _y = "foo");

#ifndef BOOST_NO_SFINAE
    assert(sfinae("foo") == 1);
    assert(sfinae(0) == 0);
#endif

    return 0;
}