tuple_traits.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*=============================================================================
  2. Copyright (c) 2016 Lee Clagett
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #include <boost/detail/lightweight_test.hpp>
  7. #include <boost/fusion/container/vector.hpp>
  8. #include <boost/fusion/tuple/tuple.hpp>
  9. #include <boost/config.hpp>
  10. #include <boost/type_traits/is_constructible.hpp>
  11. #include <boost/type_traits/is_convertible.hpp>
  12. #define FUSION_SEQUENCE boost::fusion::tuple
  13. #define FUSION_ALT_SEQUENCE boost::fusion::vector
  14. #include "traits.hpp"
  15. struct not_convertible {};
  16. /* Some construction differences in fusion::tuple from std::tuple:
  17. - Construction from elements cannot call an explicit constructor.
  18. - There is no implicit construction from elements.
  19. - Construction from std::pair is _enabled_ when tuple is not of size 2.
  20. - Construction from tuple is _enabled_ when destination tuple is of
  21. different size.
  22. - Implicit construction from std::pair can call explicit constructors on
  23. elements.
  24. - Implicit construction from tuple can call explicit constructors on
  25. elements.
  26. These differences are historical. Matching the behavior of std::tuple
  27. could break existing code, however, switching to fusion::vector would
  28. restore the historical behavior. */
  29. int
  30. main()
  31. {
  32. using namespace boost::fusion;
  33. test_convertible(false /* no conversion construction */ );
  34. BOOST_TEST((is_convertible<std::pair<int, int>, tuple<int, int> >(true)));
  35. BOOST_TEST((
  36. is_convertible<std::pair<int, int>, tuple<convertible, int> >(true)
  37. ));
  38. BOOST_TEST((
  39. is_convertible<std::pair<int, int>, tuple<int, convertible> >(true)
  40. ));
  41. BOOST_TEST((
  42. is_convertible<
  43. std::pair<int, int>, tuple<convertible, convertible>
  44. >(true)
  45. ));
  46. #if defined(FUSION_TEST_HAS_CONSTRUCTIBLE)
  47. test_constructible();
  48. BOOST_TEST((is_constructible< tuple<> >(true)));
  49. BOOST_TEST((is_constructible<tuple<>, int>(false)));
  50. BOOST_TEST((is_constructible< tuple<int> >(true)));
  51. BOOST_TEST((is_constructible<tuple<int>, int>(true)));
  52. BOOST_TEST((is_constructible<tuple<convertible>, int>(true)));
  53. BOOST_TEST((is_constructible<tuple<not_convertible>, int>(false)));
  54. BOOST_TEST((is_constructible< tuple<int>, vector<int> >(false)));
  55. BOOST_TEST((is_constructible<tuple<int>, int, int>(false)));
  56. BOOST_TEST((is_constructible< tuple<int, int> >(true)));
  57. // boost::is_constructible always fail to test ctor which takes 2 or more arguments on GCC 4.7.
  58. #if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
  59. BOOST_TEST((is_constructible<tuple<int, int>, int, int>(true)));
  60. BOOST_TEST((
  61. is_constructible<tuple<convertible, convertible>, int, int>(true)
  62. ));
  63. #endif // !(gcc < 4.7)
  64. BOOST_TEST((is_constructible<tuple<int, not_convertible>, int, int>(false)));
  65. BOOST_TEST((is_constructible<tuple<not_convertible, int>, int, int>(false)));
  66. BOOST_TEST((
  67. is_constructible<tuple<not_convertible, not_convertible>, int, int>(false)
  68. ));
  69. #if defined(BOOST_FUSION_HAS_VARIADIC_VECTOR)
  70. // C++03 fusion::tuple has constructors that can never be used
  71. BOOST_TEST((is_constructible<tuple<int, int>, int>(false)));
  72. #endif
  73. BOOST_TEST((is_constructible<tuple<int, int>, int, int, int>(false)));
  74. #endif // FUSION_TEST_HAS_CONSTRUCTIBLE
  75. return boost::report_errors();
  76. }