/Src/Dependencies/Boost/libs/parameter/test/preprocessor.cpp

http://hadesmem.googlecode.com/ · C++ · 482 lines · 390 code · 69 blank · 23 comment · 12 complexity · 0f7b8e0979fc41c7c1378c84f63fb76b MD5 · raw file

  1. // Copyright Daniel Wallin 2006. Use, modification and distribution is
  2. // subject to the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #include <boost/parameter/preprocessor.hpp>
  5. #include <boost/parameter/keyword.hpp>
  6. #include <boost/type_traits/is_const.hpp>
  7. #include <string>
  8. #include "basics.hpp"
  9. #ifndef BOOST_NO_SFINAE
  10. # include <boost/utility/enable_if.hpp>
  11. #endif
  12. namespace test {
  13. BOOST_PARAMETER_BASIC_FUNCTION((int), f, tag,
  14. (required
  15. (tester, *)
  16. (name, *)
  17. )
  18. (optional
  19. (value, *)
  20. (out(index), (int))
  21. )
  22. )
  23. {
  24. typedef typename boost::parameter::binding<
  25. Args, tag::index, int&
  26. >::type index_type;
  27. BOOST_MPL_ASSERT((boost::is_same<index_type, int&>));
  28. args[tester](
  29. args[name]
  30. , args[value | 1.f]
  31. , args[index | 2]
  32. );
  33. return 1;
  34. }
  35. BOOST_PARAMETER_BASIC_FUNCTION((int), g, tag,
  36. (required
  37. (tester, *)
  38. (name, *)
  39. )
  40. (optional
  41. (value, *)
  42. (out(index), (int))
  43. )
  44. )
  45. {
  46. typedef typename boost::parameter::binding<
  47. Args, tag::index, int const&
  48. >::type index_type;
  49. BOOST_MPL_ASSERT((boost::is_same<index_type, int const&>));
  50. args[tester](
  51. args[name]
  52. , args[value | 1.f]
  53. , args[index | 2]
  54. );
  55. return 1;
  56. }
  57. BOOST_PARAMETER_FUNCTION((int), h, tag,
  58. (required
  59. (tester, *)
  60. (name, *)
  61. )
  62. (optional
  63. (value, *, 1.f)
  64. (out(index), (int), 2)
  65. )
  66. )
  67. {
  68. # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
  69. && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  70. BOOST_MPL_ASSERT((boost::is_same<index_type, int>));
  71. # endif
  72. tester(
  73. name
  74. , value
  75. , index
  76. );
  77. return 1;
  78. }
  79. BOOST_PARAMETER_FUNCTION((int), h2, tag,
  80. (required
  81. (tester, *)
  82. (name, *)
  83. )
  84. (optional
  85. (value, *, 1.f)
  86. (out(index), (int), (int)value * 2)
  87. )
  88. )
  89. {
  90. # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \
  91. && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
  92. BOOST_MPL_ASSERT((boost::is_same<index_type, int>));
  93. # endif
  94. tester(
  95. name
  96. , value
  97. , index
  98. );
  99. return 1;
  100. }
  101. struct base
  102. {
  103. template <class Args>
  104. base(Args const& args)
  105. {
  106. args[tester](
  107. args[name]
  108. , args[value | 1.f]
  109. , args[index | 2]
  110. );
  111. }
  112. };
  113. struct class_ : base
  114. {
  115. BOOST_PARAMETER_CONSTRUCTOR(class_, (base), tag,
  116. (required
  117. (tester, *)
  118. (name, *)
  119. )
  120. (optional
  121. (value, *)
  122. (index, *)
  123. )
  124. )
  125. BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag,
  126. (required
  127. (tester, *)
  128. (name, *)
  129. )
  130. (optional
  131. (value, *)
  132. (index, *)
  133. )
  134. )
  135. {
  136. args[tester](
  137. args[name]
  138. , args[value | 1.f]
  139. , args[index | 2]
  140. );
  141. return 1;
  142. }
  143. BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, tag,
  144. (required
  145. (tester, *)
  146. (name, *)
  147. )
  148. (optional
  149. (value, *)
  150. (index, *)
  151. )
  152. )
  153. {
  154. args[tester](
  155. args[name]
  156. , args[value | 1.f]
  157. , args[index | 2]
  158. );
  159. return 1;
  160. }
  161. BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, tag,
  162. (required
  163. (tester, *)
  164. (name, *)
  165. )
  166. (optional
  167. (value, *, 1.f)
  168. (index, *, 2)
  169. )
  170. )
  171. {
  172. tester(name, value, index);
  173. return 1;
  174. }
  175. BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, tag,
  176. (required
  177. (tester, *)
  178. (name, *)
  179. )
  180. (optional
  181. (value, *, 1.f)
  182. (index, *, 2)
  183. )
  184. )
  185. {
  186. tester(name, value, index);
  187. return 1;
  188. }
  189. BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, tag,
  190. (required
  191. (tester, *)
  192. (name, *)
  193. )
  194. (optional
  195. (value, *, 1.f)
  196. (index, *, 2)
  197. )
  198. )
  199. {
  200. tester(name, value, index);
  201. return 1;
  202. }
  203. };
  204. BOOST_PARAMETER_FUNCTION(
  205. (int), sfinae, tag,
  206. (required
  207. (name, (std::string))
  208. )
  209. )
  210. {
  211. return 1;
  212. }
  213. #ifndef BOOST_NO_SFINAE
  214. // On compilers that actually support SFINAE, add another overload
  215. // that is an equally good match and can only be in the overload set
  216. // when the others are not. This tests that the SFINAE is actually
  217. // working. On all other compilers we're just checking that
  218. // everything about SFINAE-enabled code will work, except of course
  219. // the SFINAE.
  220. template<class A0>
  221. typename boost::enable_if<boost::is_same<int,A0>, int>::type
  222. sfinae(A0 const& a0)
  223. {
  224. return 0;
  225. }
  226. #endif
  227. #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
  228. // Sun has problems with this syntax:
  229. //
  230. // template1< r* ( template2<x> ) >
  231. //
  232. // Workaround: factor template2<x> into a separate typedef
  233. typedef boost::is_convertible<boost::mpl::_, std::string> predicate;
  234. BOOST_PARAMETER_FUNCTION(
  235. (int), sfinae1, tag,
  236. (required
  237. (name, *(predicate))
  238. )
  239. )
  240. {
  241. return 1;
  242. }
  243. #else
  244. BOOST_PARAMETER_FUNCTION(
  245. (int), sfinae1, tag,
  246. (required
  247. (name, *(boost::is_convertible<boost::mpl::_, std::string>))
  248. )
  249. )
  250. {
  251. return 1;
  252. }
  253. #endif
  254. #ifndef BOOST_NO_SFINAE
  255. // On compilers that actually support SFINAE, add another overload
  256. // that is an equally good match and can only be in the overload set
  257. // when the others are not. This tests that the SFINAE is actually
  258. // working. On all other compilers we're just checking that
  259. // everything about SFINAE-enabled code will work, except of course
  260. // the SFINAE.
  261. template<class A0>
  262. typename boost::enable_if<boost::is_same<int,A0>, int>::type
  263. sfinae1(A0 const& a0)
  264. {
  265. return 0;
  266. }
  267. #endif
  268. template <class T>
  269. T const& as_lvalue(T const& x)
  270. {
  271. return x;
  272. }
  273. struct udt
  274. {
  275. udt(int foo, int bar)
  276. : foo(foo)
  277. , bar(bar)
  278. {}
  279. int foo;
  280. int bar;
  281. };
  282. BOOST_PARAMETER_FUNCTION((int), lazy_defaults, tag,
  283. (required
  284. (name, *)
  285. )
  286. (optional
  287. (value, *, name.foo)
  288. (index, *, name.bar)
  289. )
  290. )
  291. {
  292. return 0;
  293. }
  294. } // namespace test
  295. int main()
  296. {
  297. using namespace test;
  298. f(
  299. values(S("foo"), 1.f, 2)
  300. , S("foo")
  301. );
  302. f(
  303. tester = values(S("foo"), 1.f, 2)
  304. , name = S("foo")
  305. );
  306. int index_lvalue = 2;
  307. f(
  308. tester = values(S("foo"), 1.f, 2)
  309. , name = S("foo")
  310. , value = 1.f
  311. , test::index = index_lvalue
  312. );
  313. f(
  314. values(S("foo"), 1.f, 2)
  315. , S("foo")
  316. , 1.f
  317. , index_lvalue
  318. );
  319. g(
  320. values(S("foo"), 1.f, 2)
  321. , S("foo")
  322. , 1.f
  323. #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  324. , as_lvalue(2)
  325. #else
  326. , 2
  327. #endif
  328. );
  329. h(
  330. values(S("foo"), 1.f, 2)
  331. , S("foo")
  332. , 1.f
  333. #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
  334. , as_lvalue(2)
  335. #else
  336. , 2
  337. #endif
  338. );
  339. h2(
  340. tester = values(S("foo"), 1.f, 2)
  341. , name = S("foo")
  342. , value = 1.f
  343. );
  344. class_ x(
  345. values(S("foo"), 1.f, 2)
  346. , S("foo"), test::index = 2
  347. );
  348. x.f(
  349. values(S("foo"), 1.f, 2)
  350. , S("foo")
  351. );
  352. x.f(
  353. tester = values(S("foo"), 1.f, 2)
  354. , name = S("foo")
  355. );
  356. x.f2(
  357. values(S("foo"), 1.f, 2)
  358. , S("foo")
  359. );
  360. x.f2(
  361. tester = values(S("foo"), 1.f, 2)
  362. , name = S("foo")
  363. );
  364. class_ const& x_const = x;
  365. x_const.f(
  366. values(S("foo"), 1.f, 2)
  367. , S("foo")
  368. );
  369. x_const.f(
  370. tester = values(S("foo"), 1.f, 2)
  371. , name = S("foo")
  372. );
  373. x_const.f2(
  374. values(S("foo"), 1.f, 2)
  375. , S("foo")
  376. );
  377. x_const.f2(
  378. tester = values(S("foo"), 1.f, 2)
  379. , name = S("foo")
  380. );
  381. x_const.f2(
  382. tester = values(S("foo"), 1.f, 2)
  383. , name = S("foo")
  384. );
  385. class_::f_static(
  386. values(S("foo"), 1.f, 2)
  387. , S("foo")
  388. );
  389. class_::f_static(
  390. tester = values(S("foo"), 1.f, 2)
  391. , name = S("foo")
  392. );
  393. #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
  394. assert(sfinae("foo") == 1);
  395. assert(sfinae(1) == 0);
  396. # if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
  397. // Sun actually eliminates the desired overload for some reason.
  398. // Disabling this part of the test because SFINAE abilities are
  399. // not the point of this test.
  400. assert(sfinae1("foo") == 1);
  401. # endif
  402. assert(sfinae1(1) == 0);
  403. #endif
  404. lazy_defaults(
  405. name = udt(0,1)
  406. );
  407. lazy_defaults(
  408. name = 0
  409. , value = 1
  410. , test::index = 2
  411. );
  412. return 0;
  413. }