| 1 | // |
| 2 | // Copyright 2015-2024 Antony Polukhin. |
| 3 | // |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See |
| 5 | // accompanying file LICENSE_1_0.txt or copy at |
| 6 | // http://www.boost.org/LICENSE_1_0.txt) |
| 7 | |
| 8 | #include <boost/type_index/ctti_type_index.hpp> |
| 9 | |
| 10 | #include <algorithm> |
| 11 | #include <string> |
| 12 | |
| 13 | #include <boost/core/lightweight_test.hpp> |
| 14 | |
| 15 | const char* hello1 = "Hello word" ; |
| 16 | const char* hello1_end = hello1 + sizeof("Hello word" ); |
| 17 | const char* hello2 = "Hello word, pal!" ; |
| 18 | const char* hello2_end = hello2 + sizeof("Hello word, pal!" ); |
| 19 | |
| 20 | void strcmp_same() { |
| 21 | using boost::typeindex::detail::constexpr_strcmp; |
| 22 | |
| 23 | BOOST_TEST( |
| 24 | constexpr_strcmp(hello1, hello1) == 0 |
| 25 | ); |
| 26 | |
| 27 | BOOST_TEST( |
| 28 | constexpr_strcmp(hello2, hello2) == 0 |
| 29 | ); |
| 30 | |
| 31 | BOOST_TEST( |
| 32 | constexpr_strcmp(hello1, hello2) != 0 |
| 33 | ); |
| 34 | |
| 35 | BOOST_TEST( |
| 36 | constexpr_strcmp(hello2, hello1) != 0 |
| 37 | ); |
| 38 | |
| 39 | BOOST_TEST( |
| 40 | (constexpr_strcmp(hello2, hello1) < 0) |
| 41 | == |
| 42 | (std::strcmp(hello2, hello1) < 0) |
| 43 | ); |
| 44 | |
| 45 | BOOST_TEST( |
| 46 | (constexpr_strcmp(hello1, hello2) < 0) |
| 47 | == |
| 48 | (std::strcmp(hello1, hello2) < 0) |
| 49 | ); |
| 50 | } |
| 51 | |
| 52 | void search_same() { |
| 53 | using boost::typeindex::detail::constexpr_search; |
| 54 | BOOST_TEST( |
| 55 | constexpr_search(hello1, hello1_end, hello2, hello2_end) == std::search(hello1, hello1_end, hello2, hello2_end) |
| 56 | ); |
| 57 | |
| 58 | BOOST_TEST( |
| 59 | constexpr_search(hello2, hello2_end, hello1, hello1_end) == std::search(hello2, hello2_end, hello1, hello1_end) |
| 60 | ); |
| 61 | |
| 62 | const char* word = "word" ; |
| 63 | const char* word_end = word + sizeof("word" ) - 1; |
| 64 | BOOST_TEST( |
| 65 | constexpr_search(hello1, hello1_end, word, word_end) == std::search(hello1, hello1_end, word, word_end) |
| 66 | ); |
| 67 | |
| 68 | BOOST_TEST( |
| 69 | constexpr_search(hello2, hello2_end, word, word_end) == std::search(hello2, hello2_end, word, word_end) |
| 70 | ); |
| 71 | } |
| 72 | |
| 73 | template <class T, std::size_t N> |
| 74 | BOOST_CXX14_CONSTEXPR bool in_namespace(const char (&ns)[N]) BOOST_NOEXCEPT { |
| 75 | BOOST_CXX14_CONSTEXPR const char* name = boost::typeindex::ctti_type_index::type_id<T>().raw_name(); |
| 76 | for (std::size_t i = 0; i < N - 1; ++i) |
| 77 | if (name[i] != ns[i]) |
| 78 | return false; |
| 79 | |
| 80 | return true; |
| 81 | } |
| 82 | |
| 83 | template <class T> |
| 84 | BOOST_CXX14_CONSTEXPR bool is_boost_namespace() BOOST_NOEXCEPT { |
| 85 | return in_namespace<T>("boost::" ) || in_namespace<T>("class boost::" ) || in_namespace<T>("struct boost::" ); |
| 86 | } |
| 87 | |
| 88 | void constexpr_test() { |
| 89 | using namespace boost::typeindex; |
| 90 | |
| 91 | BOOST_CXX14_CONSTEXPR ctti_type_index t_int0 = ctti_type_index::type_id<int>(); |
| 92 | (void)t_int0; |
| 93 | |
| 94 | BOOST_CXX14_CONSTEXPR ctti_type_index t_short0 = ctti_type_index::type_id<short>(); |
| 95 | (void)t_short0; |
| 96 | |
| 97 | BOOST_CXX14_CONSTEXPR ctti_type_index t_int1 = ctti_type_index::type_id<int>(); |
| 98 | (void)t_int1; |
| 99 | |
| 100 | BOOST_CXX14_CONSTEXPR ctti_type_index t_short1 = ctti_type_index::type_id<short>(); |
| 101 | (void)t_short1; |
| 102 | |
| 103 | // Following tests are known to fail on _MSC_VER == 1916. |
| 104 | #if !defined(_MSC_VER) || _MSC_VER > 1916 |
| 105 | |
| 106 | BOOST_CXX14_CONSTEXPR bool same0 = (t_int0 == t_int1); |
| 107 | BOOST_TEST(same0); |
| 108 | |
| 109 | BOOST_CXX14_CONSTEXPR bool same1 = (t_short1 == t_short0); |
| 110 | BOOST_TEST(same1); |
| 111 | |
| 112 | BOOST_CXX14_CONSTEXPR bool same2 = (t_int1 == t_int1); |
| 113 | BOOST_TEST(same2); |
| 114 | |
| 115 | BOOST_CXX14_CONSTEXPR bool same3 = (t_short0 == t_short0); |
| 116 | BOOST_TEST(same3); |
| 117 | |
| 118 | BOOST_CXX14_CONSTEXPR bool same4 = !(t_short0 < t_short0 || t_short0 > t_short0); |
| 119 | BOOST_TEST(same4); |
| 120 | |
| 121 | BOOST_CXX14_CONSTEXPR bool same5 = (t_short0 <= t_short0 && t_short0 >= t_short0); |
| 122 | BOOST_TEST(same5); |
| 123 | |
| 124 | |
| 125 | BOOST_CXX14_CONSTEXPR bool not_same0 = (t_int0 != t_short1); |
| 126 | BOOST_TEST(not_same0); |
| 127 | |
| 128 | BOOST_CXX14_CONSTEXPR bool not_same1 = (t_int1 != t_short0); |
| 129 | BOOST_TEST(not_same1); |
| 130 | |
| 131 | BOOST_CXX14_CONSTEXPR bool not_same2 = (t_int1 < t_short0 || t_int1 > t_short0); |
| 132 | BOOST_TEST(not_same2); |
| 133 | |
| 134 | |
| 135 | BOOST_CXX14_CONSTEXPR const char* int_name = t_int0.name(); |
| 136 | BOOST_TEST(*int_name != '\0'); |
| 137 | |
| 138 | BOOST_CXX14_CONSTEXPR const char* short_name = t_short0.name(); |
| 139 | BOOST_TEST(*short_name != '\0'); |
| 140 | |
| 141 | BOOST_CXX14_CONSTEXPR bool in_namespace = is_boost_namespace<ctti_type_index>(); |
| 142 | BOOST_TEST(in_namespace); |
| 143 | |
| 144 | BOOST_CXX14_CONSTEXPR bool not_in_namespace = !is_boost_namespace<std::string>(); |
| 145 | BOOST_TEST(not_in_namespace); |
| 146 | |
| 147 | #endif // #if !defined(_MSC_VER) || _MSC_VER > 1916 |
| 148 | } |
| 149 | |
| 150 | |
| 151 | int main() { |
| 152 | strcmp_same(); |
| 153 | search_same(); |
| 154 | constexpr_test(); |
| 155 | return boost::report_errors(); |
| 156 | } |
| 157 | |
| 158 | |