test.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*=============================================================================
  2. Copyright (c) 2017 Paul Fultz II
  3. test.hpp
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #ifndef GUARD_TEST_H
  8. #define GUARD_TEST_H
  9. #include <type_traits>
  10. #include <tuple>
  11. #include <iostream>
  12. #include <functional>
  13. #include <vector>
  14. #include <memory>
  15. #include <boost/hof/detail/forward.hpp>
  16. #ifndef BOOST_HOF_HAS_STATIC_TEST_CHECK
  17. #if (defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7) || defined(_MSC_VER)
  18. #define BOOST_HOF_HAS_STATIC_TEST_CHECK 0
  19. #else
  20. #define BOOST_HOF_HAS_STATIC_TEST_CHECK 1
  21. #endif
  22. #endif
  23. #define BOOST_HOF_PP_CAT(x, y) BOOST_HOF_PP_PRIMITIVE_CAT(x, y)
  24. #define BOOST_HOF_PP_PRIMITIVE_CAT(x, y) x ## y
  25. namespace boost { namespace hof { namespace test {
  26. typedef std::function<void()> test_case;
  27. static std::vector<test_case> test_cases;
  28. struct auto_register
  29. {
  30. auto_register(test_case tc)
  31. {
  32. test_cases.push_back(tc);
  33. }
  34. };
  35. #define BOOST_HOF_DETAIL_TEST_CASE(name) \
  36. struct name \
  37. { void operator()() const; }; \
  38. static boost::hof::test::auto_register BOOST_HOF_PP_CAT(name, _register) = boost::hof::test::auto_register(name()); \
  39. void name::operator()() const
  40. template<class T>
  41. T bare(const T&);
  42. template<class T>
  43. inline void unused(T&&) {}
  44. }}} // namespace boost::hof
  45. #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
  46. #define BOOST_HOF_STATIC_AUTO constexpr auto
  47. #else
  48. #define BOOST_HOF_STATIC_AUTO const constexpr auto
  49. #endif
  50. #define STATIC_ASSERT_SAME(...) static_assert(std::is_same<__VA_ARGS__>::value, "Types are not the same")
  51. #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
  52. #define STATIC_ASSERT_MOVE_ONLY(T)
  53. #else
  54. #define STATIC_ASSERT_MOVE_ONLY(T) static_assert(!std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value, "Not movable")
  55. #endif
  56. #if defined(__GNUC__) && !defined (__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ < 7
  57. #define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T)
  58. #else
  59. #define STATIC_ASSERT_NOT_DEFAULT_CONSTRUCTIBLE(T) static_assert(!std::is_default_constructible<T>::value, "Default constructible")
  60. #endif
  61. #define STATIC_ASSERT_EMPTY(x) static_assert(std::is_empty<decltype(boost::hof::test::bare(x))>::value, "Not empty");
  62. #define BOOST_HOF_TEST_CASE() BOOST_HOF_DETAIL_TEST_CASE(BOOST_HOF_PP_CAT(test_, __LINE__))
  63. #define BOOST_HOF_STATIC_TEST_CASE() struct BOOST_HOF_PP_CAT(test_, __LINE__)
  64. #define BOOST_HOF_TEST_TEMPLATE(...) typedef std::integral_constant<int, sizeof(__VA_ARGS__)> BOOST_HOF_PP_CAT(test_template_, __LINE__)
  65. #define BOOST_HOF_TEST_CHECK(...) if (!(__VA_ARGS__)) std::cout << "***** FAILED *****: " << #__VA_ARGS__ << "@" << __FILE__ << ": " << __LINE__ << std::endl
  66. #define BOOST_HOF_STRINGIZE(...) #__VA_ARGS__
  67. #if BOOST_HOF_HAS_STATIC_TEST_CHECK
  68. #define BOOST_HOF_STATIC_TEST_CHECK(...) static_assert(__VA_ARGS__, BOOST_HOF_STRINGIZE(__VA_ARGS__))
  69. #else
  70. #define BOOST_HOF_STATIC_TEST_CHECK(...)
  71. #endif
  72. #ifndef BOOST_HOF_HAS_CONSTEXPR_TUPLE
  73. #define BOOST_HOF_HAS_CONSTEXPR_TUPLE BOOST_HOF_HAS_STD_14
  74. #endif
  75. struct binary_class
  76. {
  77. template<class T, class U>
  78. constexpr T operator()(T x, U y) const noexcept
  79. {
  80. return x+y;
  81. }
  82. };
  83. struct mutable_class
  84. {
  85. template<class F>
  86. struct result;
  87. template<class F, class T, class U>
  88. struct result<F(T&, U)>
  89. {
  90. typedef T type;
  91. };
  92. template<class T, class U>
  93. T operator()(T & x, U y) const
  94. {
  95. return x+=y;
  96. }
  97. };
  98. struct unary_class
  99. {
  100. template<class T>
  101. constexpr T&& operator()(T&& x) const noexcept
  102. {
  103. return boost::hof::forward<T>(x);
  104. }
  105. };
  106. struct void_class
  107. {
  108. template<class T>
  109. void operator()(T) const
  110. {
  111. }
  112. };
  113. struct mono_class
  114. {
  115. constexpr int operator()(int x) const
  116. {
  117. return x+1;
  118. }
  119. };
  120. struct tuple_class
  121. {
  122. // Note: Taking the tuple by value causes the compiler to ICE on gcc 4.7
  123. // when called in a constexpr context.
  124. template<class T>
  125. constexpr int operator()(const T& t) const
  126. {
  127. return std::get<0>(t) + 1;
  128. }
  129. };
  130. template<class R>
  131. struct explicit_class
  132. {
  133. template<class T>
  134. R operator()(T x)
  135. {
  136. return static_cast<R>(x);
  137. }
  138. };
  139. struct move_class
  140. {
  141. std::unique_ptr<int> i;
  142. move_class() : i(new int(0))
  143. {}
  144. template<class T, class U>
  145. constexpr T operator()(T x, U y) const
  146. {
  147. return x+y+*i;
  148. }
  149. };
  150. int main()
  151. {
  152. for(const auto& tc: boost::hof::test::test_cases) tc();
  153. return 0;
  154. }
  155. #endif