detail_detect_test.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Copyright 2015-2017 Hans Dembinski
  2. //
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <array>
  7. #include <boost/core/lightweight_test.hpp>
  8. #include <boost/core/lightweight_test_trait.hpp>
  9. #include <boost/histogram/axis/integer.hpp>
  10. #include <boost/histogram/axis/regular.hpp>
  11. #include <boost/histogram/axis/variable.hpp>
  12. #include <boost/histogram/axis/variant.hpp>
  13. #include <boost/histogram/detail/detect.hpp>
  14. #include <boost/histogram/unlimited_storage.hpp>
  15. #include <deque>
  16. #include <initializer_list>
  17. #include <map>
  18. #include <string>
  19. #include <type_traits>
  20. #include <unordered_map>
  21. #include <utility>
  22. #include <vector>
  23. #include "std_ostream.hpp"
  24. #include "throw_exception.hpp"
  25. #include "utility_allocator.hpp"
  26. using namespace boost::histogram;
  27. using namespace boost::histogram::detail;
  28. int main() {
  29. // has_method_value*
  30. {
  31. struct A {};
  32. struct B {
  33. A value(int) const { return {}; }
  34. };
  35. struct C {
  36. char value(int) const { return 0; }
  37. };
  38. BOOST_TEST_TRAIT_FALSE((has_method_value<A>));
  39. BOOST_TEST_TRAIT_TRUE((has_method_value<B>));
  40. BOOST_TEST_TRAIT_TRUE((has_method_value<C>));
  41. }
  42. // has_method_options
  43. {
  44. struct A {};
  45. struct B {
  46. void options() {}
  47. };
  48. BOOST_TEST_TRAIT_FALSE((has_method_options<A>));
  49. BOOST_TEST_TRAIT_TRUE((has_method_options<B>));
  50. }
  51. // has_method_metadata
  52. {
  53. struct A {};
  54. struct B {
  55. void metadata();
  56. };
  57. BOOST_TEST_TRAIT_FALSE((has_method_metadata<A>));
  58. BOOST_TEST_TRAIT_TRUE((has_method_metadata<B>));
  59. }
  60. // has_method_update
  61. {
  62. struct A {};
  63. struct B {
  64. void update(int) {}
  65. };
  66. using C = axis::integer<int, axis::null_type, use_default>;
  67. BOOST_TEST_TRAIT_FALSE((has_method_update<A>));
  68. BOOST_TEST_TRAIT_TRUE((has_method_update<B>));
  69. BOOST_TEST_TRAIT_TRUE((has_method_update<C>));
  70. }
  71. // has_method_resize
  72. {
  73. struct A {};
  74. using B = std::vector<int>;
  75. using C = std::map<int, int>;
  76. BOOST_TEST_TRAIT_FALSE((has_method_resize<A>));
  77. BOOST_TEST_TRAIT_TRUE((has_method_resize<B>));
  78. BOOST_TEST_TRAIT_FALSE((has_method_resize<C>));
  79. }
  80. // has_method_size
  81. {
  82. struct A {};
  83. using B = std::vector<int>;
  84. using C = std::map<int, int>;
  85. BOOST_TEST_TRAIT_FALSE((has_method_size<A>));
  86. BOOST_TEST_TRAIT_TRUE((has_method_size<B>));
  87. BOOST_TEST_TRAIT_TRUE((has_method_size<C>));
  88. }
  89. // has_method_clear
  90. {
  91. struct A {};
  92. using B = std::vector<int>;
  93. using C = std::map<int, int>;
  94. using D = std::array<int, 10>;
  95. BOOST_TEST_TRAIT_FALSE((has_method_clear<A>));
  96. BOOST_TEST_TRAIT_TRUE((has_method_clear<B>));
  97. BOOST_TEST_TRAIT_TRUE((has_method_clear<C>));
  98. BOOST_TEST_TRAIT_FALSE((has_method_clear<D>));
  99. }
  100. // has_allocator
  101. {
  102. struct A {};
  103. using B = std::vector<int>;
  104. using C = std::map<int, int>;
  105. using D = std::array<int, 10>;
  106. BOOST_TEST_TRAIT_FALSE((has_method_clear<A>));
  107. BOOST_TEST_TRAIT_TRUE((has_method_clear<B>));
  108. BOOST_TEST_TRAIT_TRUE((has_method_clear<C>));
  109. BOOST_TEST_TRAIT_FALSE((has_method_clear<D>));
  110. }
  111. // is_storage
  112. {
  113. struct A {};
  114. using B = std::vector<int>;
  115. using C = unlimited_storage<>;
  116. BOOST_TEST_TRAIT_FALSE((is_storage<A>));
  117. BOOST_TEST_TRAIT_FALSE((is_storage<B>));
  118. BOOST_TEST_TRAIT_TRUE((is_storage<C>));
  119. }
  120. // is_indexable
  121. {
  122. struct A {};
  123. using B = std::vector<int>;
  124. using C = std::map<int, int>;
  125. using D = std::map<A, int>;
  126. BOOST_TEST_TRAIT_FALSE((is_indexable<A>));
  127. BOOST_TEST_TRAIT_TRUE((is_indexable<B>));
  128. BOOST_TEST_TRAIT_TRUE((is_indexable<C>));
  129. BOOST_TEST_TRAIT_FALSE((is_indexable<D>));
  130. }
  131. // is_transform
  132. {
  133. struct A {};
  134. struct B {
  135. double forward(A);
  136. A inverse(double);
  137. };
  138. BOOST_TEST_TRAIT_FALSE((is_transform<A, double>));
  139. BOOST_TEST_TRAIT_TRUE((is_transform<B, A>));
  140. BOOST_TEST_TRAIT_TRUE((is_transform<axis::transform::id, double>));
  141. }
  142. // is_vector_like
  143. {
  144. struct A {};
  145. using B = std::vector<int>;
  146. using C = std::array<int, 10>;
  147. using D = std::map<unsigned, int>;
  148. using E = std::deque<int>;
  149. BOOST_TEST_TRAIT_FALSE((is_vector_like<A>));
  150. BOOST_TEST_TRAIT_TRUE((is_vector_like<B>));
  151. BOOST_TEST_TRAIT_FALSE((is_vector_like<C>));
  152. BOOST_TEST_TRAIT_FALSE((is_vector_like<D>));
  153. BOOST_TEST_TRAIT_TRUE((is_vector_like<E>));
  154. }
  155. // is_array_like
  156. {
  157. struct A {};
  158. using B = std::vector<int>;
  159. using C = std::array<int, 10>;
  160. using D = std::map<unsigned, int>;
  161. BOOST_TEST_TRAIT_FALSE((is_array_like<A>));
  162. BOOST_TEST_TRAIT_FALSE((is_array_like<B>));
  163. BOOST_TEST_TRAIT_TRUE((is_array_like<C>));
  164. BOOST_TEST_TRAIT_FALSE((is_array_like<D>));
  165. }
  166. // is_map_like
  167. {
  168. struct A {};
  169. using B = std::vector<int>;
  170. using C = std::array<int, 10>;
  171. using D = std::map<unsigned, int>;
  172. using E = std::unordered_map<unsigned, int>;
  173. BOOST_TEST_TRAIT_FALSE((is_map_like<A>));
  174. BOOST_TEST_TRAIT_FALSE((is_map_like<B>));
  175. BOOST_TEST_TRAIT_FALSE((is_map_like<C>));
  176. BOOST_TEST_TRAIT_TRUE((is_map_like<D>));
  177. BOOST_TEST_TRAIT_TRUE((is_map_like<E>));
  178. }
  179. // is_axis
  180. {
  181. struct A {};
  182. struct B {
  183. int index(double);
  184. int size() const;
  185. };
  186. struct C {
  187. int index(double);
  188. };
  189. struct D {
  190. int size();
  191. };
  192. using E = axis::variant<axis::regular<>>;
  193. BOOST_TEST_TRAIT_FALSE((is_axis<A>));
  194. BOOST_TEST_TRAIT_TRUE((is_axis<B>));
  195. BOOST_TEST_TRAIT_FALSE((is_axis<C>));
  196. BOOST_TEST_TRAIT_FALSE((is_axis<D>));
  197. BOOST_TEST_TRAIT_FALSE((is_axis<E>));
  198. }
  199. // is_iterable
  200. {
  201. using A = std::vector<int>;
  202. using B = int[3];
  203. using C = std::initializer_list<int>;
  204. BOOST_TEST_TRAIT_FALSE((is_iterable<int>));
  205. BOOST_TEST_TRAIT_TRUE((is_iterable<A>));
  206. BOOST_TEST_TRAIT_TRUE((is_iterable<B>));
  207. BOOST_TEST_TRAIT_TRUE((is_iterable<C>));
  208. }
  209. // is_streamable
  210. {
  211. struct Foo {};
  212. BOOST_TEST_TRAIT_TRUE((is_streamable<int>));
  213. BOOST_TEST_TRAIT_TRUE((is_streamable<std::string>));
  214. BOOST_TEST_TRAIT_FALSE((is_streamable<Foo>));
  215. }
  216. // is_axis_variant
  217. {
  218. struct A {};
  219. BOOST_TEST_TRAIT_FALSE((is_axis_variant<A>));
  220. BOOST_TEST_TRAIT_TRUE((is_axis_variant<axis::variant<>>));
  221. BOOST_TEST_TRAIT_TRUE((is_axis_variant<axis::variant<axis::regular<>>>));
  222. }
  223. // is_sequence_of_axis
  224. {
  225. using A = std::vector<axis::regular<>>;
  226. using B = std::vector<axis::variant<axis::regular<>>>;
  227. using C = std::vector<int>;
  228. auto v = std::vector<axis::variant<axis::regular<>, axis::integer<>>>();
  229. BOOST_TEST_TRAIT_TRUE((is_sequence_of_any_axis<A>));
  230. BOOST_TEST_TRAIT_TRUE((is_sequence_of_axis<A>));
  231. BOOST_TEST_TRAIT_FALSE((is_sequence_of_axis_variant<A>));
  232. BOOST_TEST_TRAIT_TRUE((is_sequence_of_any_axis<B>));
  233. BOOST_TEST_TRAIT_TRUE((is_sequence_of_axis_variant<B>));
  234. BOOST_TEST_TRAIT_FALSE((is_sequence_of_axis<B>));
  235. BOOST_TEST_TRAIT_FALSE((is_sequence_of_any_axis<C>));
  236. BOOST_TEST_TRAIT_TRUE((is_sequence_of_any_axis<decltype(v)>));
  237. }
  238. // has_operator_equal
  239. {
  240. struct A {};
  241. struct B {
  242. bool operator==(const B&) const { return true; }
  243. };
  244. BOOST_TEST_TRAIT_FALSE((has_operator_equal<A, A>));
  245. BOOST_TEST_TRAIT_FALSE((has_operator_equal<B, A>));
  246. BOOST_TEST_TRAIT_TRUE((has_operator_equal<B, B>));
  247. BOOST_TEST_TRAIT_TRUE((has_operator_equal<const B&, const B&>));
  248. }
  249. // has_operator_radd
  250. {
  251. struct A {};
  252. struct B {
  253. B& operator+=(const B&) { return *this; }
  254. };
  255. BOOST_TEST_TRAIT_FALSE((has_operator_radd<A, A>));
  256. BOOST_TEST_TRAIT_FALSE((has_operator_radd<B, A>));
  257. BOOST_TEST_TRAIT_TRUE((has_operator_radd<B, B>));
  258. BOOST_TEST_TRAIT_TRUE((has_operator_radd<B&, const B&>));
  259. }
  260. return boost::report_errors();
  261. }