1 //
2 // Copyright 2015-2021 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 
strcmp_same()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 
search_same()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>
in_namespace(const char (& ns)[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>
is_boost_namespace()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 
constexpr_test()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 
main()151 int main() {
152     strcmp_same();
153     search_same();
154     constexpr_test();
155     return boost::report_errors();
156 }
157 
158