1 /*
2 * Copyright 2018 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 "audio_utils_variadic_tests"
19 #include <audio_utils/variadic_utils.h>
20
21 #include <stdio.h>
22 #include <gtest/gtest.h>
23
24 // Our near expectation is 16x the bit that doesn't fit the mantissa.
25 // this works so long as we add values close in exponent with each other
26 // realizing that errors accumulate as the sqrt of N (random walk, lln, etc).
27 #define TEST_EXPECT_NEAR(e, v) \
28 EXPECT_NEAR((e), (v), abs((e) * std::numeric_limits<decltype(e)>::epsilon() * 8))
29
30 #define PRINT_AND_EXPECT_EQ(expected, expr) { \
31 auto value = (expr); \
32 printf("(%s): %s\n", #expr, std::to_string(value).c_str()); \
33 if ((expected) == (expected)) { EXPECT_EQ((expected), (value)); } \
34 EXPECT_EQ((expected) != (expected), (value) != (value)); /* nan check */\
35 }
36
37 #define PRINT_AND_EXPECT_NEAR(expected, expr) { \
38 auto ref = (expected); \
39 auto value = (expr); \
40 printf("(%s): %s\n", #expr, std::to_string(value).c_str()); \
41 TEST_EXPECT_NEAR(ref, value); \
42 }
43
TEST(variadic_tests,printing)44 TEST(variadic_tests, printing)
45 {
46 // for operator overloading...
47 using namespace android::audio_utils;
48
49 // print simple, deep value
50 std::cout << "std::make_tuple(1, 2, 3)= " << std::make_tuple(1, 2, 3) << "\n";
51 std::cout << "std::make_pair(1, std::make_pair(0, 1))= "
52 << std::make_pair(1, std::make_pair(0, 1)) << "\n";
53 }
54
TEST(variadic_tests,equivalence)55 TEST(variadic_tests, equivalence)
56 {
57 using android::audio_utils::equivalent;
58 auto deep = std::make_pair(1., std::make_pair(2, 3));
59
60 EXPECT_TRUE(equivalent(deep, deep));
61 EXPECT_TRUE(equivalent(std::make_pair(1, 2), std::make_tuple(1, 2)));
62 EXPECT_FALSE(equivalent(std::make_pair(1, 2), std::make_pair(0, 2)));
63 EXPECT_FALSE(equivalent(std::make_pair(1, 2), 1));
64 EXPECT_FALSE(equivalent(0, 2));
65 EXPECT_TRUE(equivalent(1, 1.));
66 }
67
TEST(variadic_tests,template_checks)68 TEST(variadic_tests, template_checks)
69 {
70 EXPECT_FALSE(android::audio_utils::is_variadic<double>::value);
71
72 using tuple_t = std::tuple<double, double>;
73
74 EXPECT_TRUE(android::audio_utils::is_variadic<tuple_t>::value);
75 EXPECT_TRUE(android::audio_utils::is_tuple<tuple_t>::value);
76 EXPECT_FALSE(android::audio_utils::is_pair<tuple_t>::value);
77 EXPECT_FALSE(android::audio_utils::is_array<tuple_t>::value);
78 EXPECT_FALSE(std::is_array<tuple_t>::value);
79
80 using pair_t = std::pair<double, double>;
81
82 EXPECT_TRUE(android::audio_utils::is_variadic<pair_t>::value);
83 EXPECT_FALSE(android::audio_utils::is_tuple<pair_t>::value);
84 EXPECT_TRUE(android::audio_utils::is_pair<pair_t>::value);
85 EXPECT_FALSE(android::audio_utils::is_array<pair_t>::value);
86 EXPECT_FALSE(std::is_array<pair_t>::value);
87
88 using array_t = std::array<double, 2>;
89
90 EXPECT_TRUE(android::audio_utils::is_variadic<array_t>::value);
91 EXPECT_FALSE(android::audio_utils::is_tuple<array_t>::value);
92 EXPECT_FALSE(android::audio_utils::is_pair<array_t>::value);
93 EXPECT_TRUE(android::audio_utils::is_array<array_t>::value);
94 EXPECT_FALSE(std::is_array<array_t>::value);
95
96 EXPECT_FALSE(android::audio_utils::is_iterator<char>::value);
97 EXPECT_TRUE(android::audio_utils::is_iterator<char *>::value);
98 EXPECT_TRUE(android::audio_utils::is_iterator<decltype(std::vector<int>{}.begin())>::value);
99 }
100
TEST(variadic_tests,basic_math)101 TEST(variadic_tests, basic_math)
102 {
103 // for operator overloading...
104 using namespace android::audio_utils;
105
106 using tuple_t = std::tuple<double, double>;
107 tuple_t x{1, 2};
108 tuple_t y{0, 3};
109 double z = 3;
110
111 std::cout << "x=" << x << " y=" << y << " x+y=" << (x + y) << "\n";
112 std::cout << "x=" << x << " y=" << y << " x*y=" << (x * y) << "\n";
113 std::cout << "x=" << x << " z=" << z << " x+z=" << (x + z) << "\n";
114 std::cout << "x=" << x << " z=" << z << " x*z=" << (x * z) << "\n";
115 std::cout << "x=" << x << " y=" << y << " innerProduct(x, y)=" << innerProduct(x, y) << "\n";
116 std::cout << "x=" << x << " y=" << y << " outerProduct(x, y)=" << outerProduct(x, y) << "\n";
117 std::cout << "x=" << x << " sqrt(x)=" << android::audio_utils::sqrt(x) << "\n";
118 std::cout << "x=" << x << " y=" << y
119 << " min(x, y)" << android::audio_utils::min(x, y) << "\n";
120
121 // check opequals mode
122 std::cout << "x=" << x;
123 std::cout << " x+=2" << (x += 2) << "\n";
124 std::cout << "x=" << x << " y=" << y;
125 std::cout << " x*=y" << (x *= y) << "\n";
126
127 using pair_t = std::pair<double, double>;
128 pair_t px{1, 2};
129 pair_t py{0, 3};
130
131 std::cout << "px=" << px << " py=" << py << " px+py=" << (px + py) << "\n";
132 std::cout << "px=" << px << " py=" << py << " px*py=" << (px * py) << "\n";
133 std::cout << "px=" << px << " z=" << z << " px+z=" << (px + z) << "\n";
134 std::cout << "px=" << px << " z=" << z << " px*z=" << (px * z) << "\n";
135 std::cout << "px=" << px << " py=" << py << " innerProduct(px, py)="
136 << innerProduct(px, py) << "\n";
137 std::cout << "px=" << px << " py=" << py << " outerProduct(px, py)="
138 << outerProduct(px, py) << "\n";
139
140 using array_t = std::array<double, 2>;
141 array_t ax{1, 2};
142 array_t ay{0, 3};
143
144 std::cout << "ax=" << ax << " ay=" << ay << " ax+ay=" << (ax + ay) << "\n";
145 std::cout << "ax=" << ax << " ay=" << ay << " ax*ay=" << (ax * ay) << "\n";
146 std::cout << "ax=" << ax << " z=" << z << " ax+z=" << (ax + z) << "\n";
147 std::cout << "ax=" << ax << " z=" << z << " ax*z=" << (ax * z) << "\n";
148 std::cout << "ax=" << px << " ay=" << ay << " innerProduct(ax, ay)="
149 << innerProduct(ax, ay) << "\n";
150 std::cout << "ax=" << px << " ay=" << ay << " outerProduct(ax, ay)="
151 << outerProduct(ax, ay) << "\n";
152
153 // deep math
154 auto deep = std::make_pair(1., std::make_pair(2, 3));
155 std::cout << "deep= " << deep << "\n";
156 std::cout << "deep + deep= " << deep + deep << "\n";
157 std::cout << "deep + 1= " << deep + 1 << "\n";
158 }
159