Brian Silverman | 60e3e2a | 2018-08-04 23:57:12 -0700 | [diff] [blame^] | 1 | // Boost result_of library |
| 2 | |
| 3 | // Copyright Douglas Gregor 2003-2004. Use, modification and |
| 4 | // distribution is subject to the Boost Software License, Version |
| 5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| 6 | // http://www.boost.org/LICENSE_1_0.txt) |
| 7 | |
| 8 | // Examples: |
| 9 | // To run the default test: |
| 10 | // $ cd libs/utility/test && bjam |
| 11 | // To test decltype on g++ 2.7: |
| 12 | // $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE" |
| 13 | |
| 14 | #include <boost/config.hpp> |
| 15 | |
| 16 | // For more information, see http://www.boost.org/libs/utility |
| 17 | #include <boost/utility/result_of.hpp> |
| 18 | #include <utility> |
| 19 | #include <boost/static_assert.hpp> |
| 20 | #include <boost/type_traits/is_same.hpp> |
| 21 | |
| 22 | struct int_result_type |
| 23 | { |
| 24 | typedef int result_type; |
| 25 | result_type operator()(float); |
| 26 | }; |
| 27 | |
| 28 | struct int_result_of |
| 29 | { |
| 30 | template<typename F> struct result { typedef int type; }; |
| 31 | result<int_result_of(double)>::type operator()(double); |
| 32 | result<const int_result_of(double)>::type operator()(double) const; |
| 33 | result<int_result_of()>::type operator()(); |
| 34 | result<volatile int_result_of()>::type operator()() volatile; |
| 35 | }; |
| 36 | |
| 37 | struct int_result_type_and_float_result_of_and_char_return |
| 38 | { |
| 39 | typedef int result_type; |
| 40 | template<typename F> struct result { typedef float type; }; |
| 41 | char operator()(char); |
| 42 | }; |
| 43 | |
| 44 | template<typename T> |
| 45 | struct int_result_type_template |
| 46 | { |
| 47 | typedef int result_type; |
| 48 | result_type operator()(float); |
| 49 | }; |
| 50 | |
| 51 | template<typename T> |
| 52 | struct int_result_of_template |
| 53 | { |
| 54 | template<typename F> struct result; |
| 55 | template<typename This, typename That> struct result<This(That)> { typedef int type; }; |
| 56 | typename result<int_result_of_template<T>(double)>::type operator()(double); |
| 57 | typename result<const int_result_of_template<T>(double)>::type operator()(double) const; |
| 58 | typename result<int_result_of_template<T>(double)>::type operator()(); |
| 59 | typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile; |
| 60 | }; |
| 61 | |
| 62 | template<typename T> |
| 63 | struct int_result_type_and_float_result_of_and_char_return_template |
| 64 | { |
| 65 | typedef int result_type; |
| 66 | template<typename F> struct result; |
| 67 | template<typename This, typename That> struct result<This(That)> { typedef float type; }; |
| 68 | char operator()(char); |
| 69 | }; |
| 70 | |
| 71 | template<typename T> |
| 72 | struct cv_overload_check {}; |
| 73 | |
| 74 | struct result_of_member_function_template |
| 75 | { |
| 76 | template<typename F> struct result; |
| 77 | |
| 78 | template<typename This, typename That> struct result<This(That)> { typedef That type; }; |
| 79 | template<class T> typename result<result_of_member_function_template(T)>::type operator()(T); |
| 80 | |
| 81 | template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; }; |
| 82 | template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const; |
| 83 | |
| 84 | template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; }; |
| 85 | template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile; |
| 86 | |
| 87 | template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; }; |
| 88 | template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile; |
| 89 | |
| 90 | template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; }; |
| 91 | template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T); |
| 92 | |
| 93 | template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; }; |
| 94 | template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T); |
| 95 | |
| 96 | template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; }; |
| 97 | template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T); |
| 98 | |
| 99 | template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; }; |
| 100 | template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T); |
| 101 | }; |
| 102 | |
| 103 | struct no_result_type_or_result |
| 104 | { |
| 105 | short operator()(double); |
| 106 | cv_overload_check<const short> operator()(double) const; |
| 107 | cv_overload_check<volatile short> operator()(double) volatile; |
| 108 | cv_overload_check<const volatile short> operator()(double) const volatile; |
| 109 | int operator()(); |
| 110 | cv_overload_check<const int> operator()() const; |
| 111 | cv_overload_check<volatile int> operator()() volatile; |
| 112 | cv_overload_check<const volatile int> operator()() const volatile; |
| 113 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
| 114 | short operator()(int&&); |
| 115 | int operator()(int&); |
| 116 | long operator()(int const&); |
| 117 | #endif |
| 118 | }; |
| 119 | |
| 120 | template<typename T> |
| 121 | struct no_result_type_or_result_template |
| 122 | { |
| 123 | short operator()(double); |
| 124 | cv_overload_check<const short> operator()(double) const; |
| 125 | cv_overload_check<volatile short> operator()(double) volatile; |
| 126 | cv_overload_check<const volatile short> operator()(double) const volatile; |
| 127 | int operator()(); |
| 128 | cv_overload_check<const int> operator()() const; |
| 129 | cv_overload_check<volatile int> operator()() volatile; |
| 130 | cv_overload_check<const volatile int> operator()() const volatile; |
| 131 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
| 132 | short operator()(int&&); |
| 133 | int operator()(int&); |
| 134 | long operator()(int const&); |
| 135 | #endif |
| 136 | }; |
| 137 | |
| 138 | // sfinae_tests are derived from example code from Joel de Guzman, |
| 139 | // which demonstrated the interaction between result_of and SFINAE. |
| 140 | template <typename F, typename Arg> |
| 141 | typename boost::result_of<F(Arg const&)>::type |
| 142 | sfinae_test(F f, Arg const& arg) |
| 143 | { |
| 144 | return f(arg); |
| 145 | } |
| 146 | |
| 147 | template <typename F, typename Arg> |
| 148 | typename boost::result_of<F(Arg&)>::type |
| 149 | sfinae_test(F f, Arg& arg) |
| 150 | { |
| 151 | return f(arg); |
| 152 | } |
| 153 | |
| 154 | int sfinae_test_f(int& i) |
| 155 | { |
| 156 | return i; |
| 157 | } |
| 158 | |
| 159 | struct X {}; |
| 160 | |
| 161 | int main() |
| 162 | { |
| 163 | using namespace boost; |
| 164 | |
| 165 | typedef int (*func_ptr)(float, double); |
| 166 | typedef int (&func_ref)(float, double); |
| 167 | typedef int (*func_ptr_0)(); |
| 168 | typedef int (&func_ref_0)(); |
| 169 | typedef void (*func_ptr_void)(float, double); |
| 170 | typedef void (&func_ref_void)(float, double); |
| 171 | typedef void (*func_ptr_void_0)(); |
| 172 | typedef void (&func_ref_void_0)(); |
| 173 | typedef int (X::*mem_func_ptr)(float); |
| 174 | typedef int (X::*mem_func_ptr_c)(float) const; |
| 175 | typedef int (X::*mem_func_ptr_v)(float) volatile; |
| 176 | typedef int (X::*mem_func_ptr_cv)(float) const volatile; |
| 177 | typedef int (X::*mem_func_ptr_0)(); |
| 178 | |
| 179 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); |
| 180 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); |
| 181 | BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value)); |
| 182 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value)); |
| 183 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value)); |
| 184 | BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value)); |
| 185 | |
| 186 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value)); |
| 187 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value)); |
| 188 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value)); |
| 189 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value)); |
| 190 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value)); |
| 191 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value)); |
| 192 | |
| 193 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value)); |
| 194 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value)); |
| 195 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value)); |
| 196 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); |
| 197 | |
| 198 | // Prior to decltype, result_of could not deduce the return type |
| 199 | // of nullary function objects unless they exposed a result_type. |
| 200 | #if defined(BOOST_RESULT_OF_USE_DECLTYPE) |
| 201 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value)); |
| 202 | BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value)); |
| 203 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value)); |
| 204 | BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value)); |
| 205 | #else |
| 206 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value)); |
| 207 | BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); |
| 208 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value)); |
| 209 | BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); |
| 210 | #endif |
| 211 | |
| 212 | // Prior to decltype, result_of ignored a nested result<> if |
| 213 | // result_type was defined. After decltype, result_of deduces the |
| 214 | // actual return type of the function object, ignoring both |
| 215 | // result<> and result_type. |
| 216 | #if defined(BOOST_RESULT_OF_USE_DECLTYPE) |
| 217 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value)); |
| 218 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value)); |
| 219 | #else |
| 220 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); |
| 221 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); |
| 222 | #endif |
| 223 | |
| 224 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); |
| 225 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); |
| 226 | |
| 227 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); |
| 228 | BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); |
| 229 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value)); |
| 230 | BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value)); |
| 231 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value)); |
| 232 | BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value)); |
| 233 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value)); |
| 234 | BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value)); |
| 235 | BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value)); |
| 236 | BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value)); |
| 237 | BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value)); |
| 238 | BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); |
| 239 | BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value)); |
| 240 | |
| 241 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value)); |
| 242 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value)); |
| 243 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value)); |
| 244 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value)); |
| 245 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value)); |
| 246 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value)); |
| 247 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value)); |
| 248 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value)); |
| 249 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value)); |
| 250 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value)); |
| 251 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value)); |
| 252 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); |
| 253 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value)); |
| 254 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value)); |
| 255 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(void)>::type, int>::value)); |
| 256 | |
| 257 | BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value)); |
| 258 | BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value)); |
| 259 | BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value)); |
| 260 | BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value)); |
| 261 | BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); |
| 262 | BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); |
| 263 | BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); |
| 264 | BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); |
| 265 | |
| 266 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value)); |
| 267 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value)); |
| 268 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value)); |
| 269 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value)); |
| 270 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); |
| 271 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); |
| 272 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); |
| 273 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); |
| 274 | |
| 275 | typedef int (*pf_t)(int); |
| 276 | BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value)); |
| 277 | BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value)); |
| 278 | |
| 279 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value)); |
| 280 | BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value)); |
| 281 | |
| 282 | #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
| 283 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value)); |
| 284 | BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value)); |
| 285 | BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value)); |
| 286 | BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value)); |
| 287 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value)); |
| 288 | BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value)); |
| 289 | BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value)); |
| 290 | BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value)); |
| 291 | |
| 292 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value)); |
| 293 | BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value)); |
| 294 | BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value)); |
| 295 | BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value)); |
| 296 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, int>::value)); |
| 297 | BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value)); |
| 298 | BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value)); |
| 299 | BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value)); |
| 300 | |
| 301 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr&(char, float)>::type, int>::value)); |
| 302 | BOOST_STATIC_ASSERT((is_same<result_of<func_ptr const&(char, float)>::type, int>::value)); |
| 303 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of&(double)>::type, int>::value)); |
| 304 | BOOST_STATIC_ASSERT((is_same<result_of<int_result_of const&(double)>::type, int>::value)); |
| 305 | |
| 306 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
| 307 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value)); |
| 308 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value)); |
| 309 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value)); |
| 310 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value)); |
| 311 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value)); |
| 312 | BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value)); |
| 313 | #endif |
| 314 | #endif |
| 315 | |
| 316 | #if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
| 317 | int i = 123; |
| 318 | sfinae_test(sfinae_test_f, i); |
| 319 | #endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) |
| 320 | |
| 321 | return 0; |
| 322 | } |