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
|
///////////////////////////////////////////////////////////////////////////////
// noinvoke.hpp
//
// Copyright 2008 Eric Niebler. Distributed under 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/proto/core.hpp>
#include <boost/proto/transform/make.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/test/unit_test.hpp>
namespace proto=boost::proto;
using proto::_;
struct Test
: proto::when<
_
, proto::noinvoke<
// This remove_pointer invocation is bloked by noinvoke
boost::remove_pointer<
// This add_pointer invocation is *not* blocked by noinvoke
boost::add_pointer<_>
>
>()
>
{};
struct Test2
: proto::when<
_
// This add_pointer gets invoked because a substitution takes place
// within it.
, boost::add_pointer<
proto::noinvoke<
// This remove_pointer invocation is bloked by noinvoke
boost::remove_pointer<
// This add_pointer invocation is *not* blocked by noinvoke
boost::add_pointer<_>
>
>
>()
>
{};
template<typename T, typename U>
struct select2nd
{
typedef U type;
};
struct Test3
: proto::when<
_
// This add_pointer gets invoked because a substitution takes place
// within it.
, select2nd<
void
, proto::noinvoke<
// This remove_pointer invocation is bloked by noinvoke
select2nd<
void
// This add_pointer invocation is *not* blocked by noinvoke
, boost::add_pointer<_>
>
>
>()
>
{};
void test_noinvoke()
{
typedef proto::terminal<int>::type Int;
Int i = {42};
BOOST_MPL_ASSERT((
boost::is_same<
boost::result_of<Test(Int)>::type
, boost::remove_pointer<Int *>
>
));
boost::remove_pointer<Int *> t = Test()(i);
BOOST_MPL_ASSERT((
boost::is_same<
boost::result_of<Test2(Int)>::type
, boost::remove_pointer<Int *> *
>
));
boost::remove_pointer<Int *> * t2 = Test2()(i);
BOOST_MPL_ASSERT((
boost::is_same<
boost::result_of<Test3(Int)>::type
, select2nd<void, Int *>
>
));
select2nd<void, Int *> t3 = Test3()(i);
}
using namespace boost::unit_test;
///////////////////////////////////////////////////////////////////////////////
// init_unit_test_suite
//
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite *test = BOOST_TEST_SUITE("test proto::noinvoke");
test->add(BOOST_TEST_CASE(&test_noinvoke));
return test;
}
|