Ticket #11705: phxfunction_test_problem.cpp

File phxfunction_test_problem.cpp, 3.4 KB (added by David Williams <bateyware@…>, 7 years ago)

Small test program to illustrate the problem.

Line 
1/***
2*
3* Test program to illustrate the problem:
4*
5* "Phoenix function with reference parameter fails to compile under clang 3.5 with C++ 11 support"
6*
7* Author: David Williams
8*
9* Boost version: 1.59
10*
11* Compiler: Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
12*
13* Program built using C++ 11 support.
14*
15* Test program based on the phoenix test program function_tests.cpp.
16*
17***/
18
19
20#include <iostream>
21#include <cmath>
22#include <boost/detail/lightweight_test.hpp>
23#include <boost/phoenix/core.hpp>
24#include <boost/phoenix/operator.hpp>
25#include <boost/phoenix/function.hpp>
26
27#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
28#include <boost/mpl/multiplies.hpp>
29#undef BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
30
31
32/**
33 * Defines a simple phoenix function that allows a flag to be set depending on the integer
34 * value used to initiaise the object.
35 *
36 **/
37struct add_int_impl
38{
39 typedef int result_type;
40
41
42 add_int_impl(int v)
43 {
44 _value=v;
45 }
46
47 /*
48 * Need this defined for the call BOOST_TEST(add_int(arg1)(flag) == (4)); to compile when
49 * the flags BOOST_RESULT_OF_TR1 or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK are NOT used.
50 *
51 * Note that both operator functions must be const for them to be valid phoenix functions.
52 * This function compiles OK both with and without the int operator()(bool& flag) being defined.
53 */
54/****
55 int operator()(int a) const
56 {
57 std::cout << "int operator()(int a) called" << std::endl;
58 return a + _value;
59 }
60****/
61
62 /*
63 * This can be compiled with no other overloaded operators if we define the param as
64 * (const bool& flag) rather than just (bool& flag)
65 * But a const reference paramter is not useful here as we want to change the flag
66 * depending on the stored integer _value.
67 *
68 */
69 int operator()(bool& flag) const
70 {
71 std::cout << "int operator()(bool& flag) called" << std::endl;
72 if (_value == 4)
73 flag=true;
74 return _value;
75 }
76
77 int _value;
78};
79
80
81// Initialise the function with the value 4.
82boost::phoenix::function<add_int_impl> add_int(4);
83
84int main()
85{
86 using boost::phoenix::arg_names::arg1;
87
88 int i5 = 5;
89 bool flag=false;
90
91 /**
92 * Test invoking the function object with a bool flag as a reference parameter.
93 *
94 * This call will only compile under Apple's version of clang 3.5 C++ 11 when one or both of the
95 * following conditions are met;
96 *
97 * 1) The int operator()(int a) const is also defined
98 *
99 * 2) One of the following flags is defined:
100 *
101 * BOOST_RESULT_OF_TR1
102 * BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
103 *
104 * The program also compiles if the function signature is changed to use a const
105 * reference parameter, i.e int operator()(const bool& flag) const.
106 * However this then means that the parameter value cannot be
107 * modified within the body of the function as required.
108 *
109 * The problem does not occur if the program is compiled using C++ 98 compatibility mode.
110 *
111 **/
112
113 BOOST_TEST(add_int(arg1)(flag) == (4));
114
115 /**
116 * This tests the int operator()(int a) const which under C++ 11 can be defined standalone or
117 * with the int operator()(bool& flag) const also defined. The flags BOOST_RESULT_OF_TR1
118 * and BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK are then NOT required.
119 */
120 //BOOST_TEST(add_int(arg1)(i5) == (5+4));
121
122 return boost::report_errors();
123}