1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "TypeTraits_test"
19
20#include <gtest/gtest.h>
21
22#include <media/stagefright/foundation/TypeTraits.h>
23
24namespace android {
25
26class TypeTraitsTest : public ::testing::Test {
27protected:
28    enum A { };
29    enum UA : uint32_t { };
30    enum IA : int32_t { };
31};
32
33// =========== basic sanity tests for type-support templates
34TEST_F(TypeTraitsTest, StaticTests) {
35
36    // ============ is_integral_or_enum
37
38    static_assert(!std::is_integral<A>::value, "enums should not be integral");
39    static_assert(!std::is_integral<UA>::value, "enums should not be integral");
40    static_assert(!std::is_integral<IA>::value, "enums should not be integral");
41    static_assert(is_integral_or_enum<A>::value, "enums should be integral_or_enum");
42    static_assert(is_integral_or_enum<UA>::value, "enums should be integral_or_enum");
43    static_assert(is_integral_or_enum<IA>::value, "enums should be integral_or_enum");
44    static_assert(is_integral_or_enum<int>::value, "ints should be integral_or_enum");
45    static_assert(is_integral_or_enum<unsigned>::value, "unsigned ints should be integral_or_enum");
46    static_assert(!is_integral_or_enum<float>::value, "floats should not be integral_or_enum");
47
48    // ============ is_unsigned_integral
49
50    static_assert(!std::is_unsigned<UA>::value,
51                  "unsigned enums should not be unsigned");
52    static_assert(!std::is_unsigned<IA>::value,
53                  "unsigned enums should not be unsigned");
54    static_assert(std::is_unsigned<typename std::underlying_type<UA>::type>::value,
55                  "underlying type of unsigned enums should be unsigned");
56    static_assert(!std::is_unsigned<typename std::underlying_type<IA>::type>::value,
57                  "underlying type of unsigned enums should be unsigned");
58    static_assert(is_unsigned_integral<UA>::value,
59                  "unsigned enums should be unsigned_integral");
60    static_assert(!is_unsigned_integral<IA>::value,
61                  "signed enums should not be unsigned_integral");
62    static_assert(is_unsigned_integral<unsigned>::value,
63                  "unsigned ints should be unsigned_integral");
64    static_assert(!is_unsigned_integral<int>::value,
65                  "ints should not be unsigned_integral");
66    static_assert(!is_unsigned_integral<float>::value,
67                  "floats should not be unsigned_integral");
68
69    // ============ is_signed_integral
70
71    static_assert(!std::is_signed<UA>::value,
72                  "unsigned enums should not be signed");
73    static_assert(!std::is_signed<IA>::value,
74                  "unsigned enums should not be signed");
75    static_assert(!std::is_signed<typename std::underlying_type<UA>::type>::value,
76                  "underlying type of unsigned enums should be signed");
77    static_assert(std::is_signed<typename std::underlying_type<IA>::type>::value,
78                  "underlying type of unsigned enums should be signed");
79    static_assert(!is_signed_integral<UA>::value,
80                  "unsigned enums should not be signed_integral");
81    static_assert(is_signed_integral<IA>::value,
82                  "signed enums should be signed_integral");
83    static_assert(!is_signed_integral<unsigned>::value,
84                  "unsigned ints should not be signed_integral");
85    static_assert(is_signed_integral<int>::value,
86                  "ints should be signed_integral");
87    static_assert(!is_signed_integral<float>::value,
88                  "floats should not be signed_integral");
89
90    // ============ underlying_integral_type
91
92    static_assert(std::is_same<uint64_t, typename underlying_integral_type<uint64_t>::type>::value,
93                  "underlying integral type of uint64_t should be uint64_t");
94    static_assert(std::is_same<uint32_t, typename underlying_integral_type<UA>::type>::value,
95                  "underlying integral type of uint32_t based enums should be uint32_t");
96    static_assert(std::is_same<int64_t, typename underlying_integral_type<int64_t>::type>::value,
97                  "underlying integral type of int64_t should be int64_t");
98    static_assert(std::is_same<int32_t, typename underlying_integral_type<IA>::type>::value,
99                  "underlying integral type of int32_t based enums should be int32_t");
100    //typedef underlying_integral_type<float>::type no_type;
101    static_assert(std::is_same<void, typename underlying_integral_type<float, void>::type>::value,
102                  "underlying integral type of float cannot be specified");
103
104    // ============ is_one_of
105
106    static_assert(!is_one_of<int>::value, "int shouldn't be one of {}");
107    static_assert(!is_one_of<int, unsigned>::value, "int shouldn't be one of {unsigned}");
108    static_assert(!is_one_of<int, unsigned, float>::value,
109                  "int shouldn't be one of {unsigned, float}");
110    static_assert(is_one_of<int, int>::value, "int should be one of {int}");
111    static_assert(is_one_of<int, int, float>::value, "int should be one of {int, float}");
112    static_assert(is_one_of<int, float, int>::value, "int should be one of {float, int}");
113    static_assert(is_one_of<int, float, int, unsigned>::value,
114                  "int should be one of {float, int, unsigned}");
115    static_assert(is_one_of<int, float, unsigned, int>::value,
116                  "int should be one of {float, unsigned, int}");
117    static_assert(!is_one_of<int, int&>::value, "int shouldn't be one of {int&}");
118
119    // ============ are_unique
120
121    static_assert(are_unique<>::value, "{} should be unique");
122    static_assert(are_unique<int>::value, "{int} should be unique");
123    static_assert(are_unique<int, float>::value, "{int, float} should be unique");
124    static_assert(!are_unique<int, int>::value, "{int, int} shouldn't be unique");
125    static_assert(!are_unique<int, float, int>::value, "{int, float, int} shouldn't be unique");
126    static_assert(!are_unique<float, int, int>::value, "{float, int, int} shouldn't be unique");
127    static_assert(!are_unique<int, int, float>::value, "{int, int, float} shouldn't be unique");
128
129    // ============ find_first
130
131    static_assert(find_first<int>::index == 0, "int is not in {}");
132    static_assert(find_first<int, unsigned>::index == 0, "int is not in {unsigned}");
133    static_assert(find_first<int, unsigned, float>::index == 0, "int is not in {unsigned, float}");
134    static_assert(find_first<int, int>::index == 1, "int is 1st in {int}");
135    static_assert(find_first<int, int, float>::index == 1, "int is 1st in {int, float}");
136    static_assert(find_first<int, float, int>::index == 2, "int is 2nd in {float, int}");
137    static_assert(find_first<int, float, int, unsigned>::index == 2,
138                  "int is 2nd in {float, int, unsigned}");
139    static_assert(find_first<int, float, int, unsigned>::index == 2,
140                  "int is 2nd and 3rd in {float, int, int, unsigned}");
141    static_assert(find_first<int, float, unsigned, int>::index == 3,
142                  "int is 3rd in {float, unsigned, int}");
143    static_assert(find_first<int, int&>::index == 0, "int is not in {int&}");
144
145    // ============ find_first_convertible_to
146
147    static_assert(find_first_convertible_to<int>::index == 0, "int is not convertible to {}");
148    static_assert(find_first_convertible_to<int, unsigned*>::index == 0,
149                  "int is not convertible to {unsigned*}");
150    static_assert(find_first_convertible_to<int, unsigned*, float&>::index == 0,
151                  "int is not convertible to {unsigned, float&}");
152    static_assert(find_first_convertible_to<int, int>::index == 1, "int is convertible to {int}");
153    static_assert(find_first_convertible_to<int, unsigned, int>::index == 1,
154                  "int is convertible to 1st of {unsigned, int}");
155    static_assert(find_first_convertible_to<int, int&, float>::index == 2,
156                  "int is convertible to 2nd of {int&, float}");
157    static_assert(find_first_convertible_to<float, float*, int, unsigned>::index == 2,
158                  "float is convertible to 2nd of {float*, int, unsigned}");
159    static_assert(find_first_convertible_to<float, void, float[1], int>::index == 3,
160                  "int is 3rd convertible to {void, float[], int}");
161    static_assert(find_first_convertible_to<int&, const int&>::index == 1,
162                  "int& is convertible to {const int&}");
163    static_assert(find_first_convertible_to<const int&, int&>::index == 0,
164                  "const int& is not convertible to {int&}");
165}
166
167} // namespace android
168