Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-utils.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
38#include <gtest/gtest.h>
39#include "../ahUtils.H"
40#include <vector>
41#include <fstream>
42#include <cstdio>
43
44// Tests for is_even() and is_odd()
45TEST(AhUtilsTest, EvenOdd) {
46 EXPECT_TRUE(Aleph::is_even(0));
47 EXPECT_FALSE(Aleph::is_odd(0));
48 EXPECT_TRUE(Aleph::is_even(2));
49 EXPECT_FALSE(Aleph::is_odd(2));
50 EXPECT_FALSE(Aleph::is_even(1));
51 EXPECT_TRUE(Aleph::is_odd(1));
52 EXPECT_TRUE(Aleph::is_even(-4));
53 EXPECT_FALSE(Aleph::is_odd(-4));
54 EXPECT_FALSE(Aleph::is_even(-5));
55 EXPECT_TRUE(Aleph::is_odd(-5));
56}
57
58// Tests for nibble_to_char() and char_to_nibble()
59TEST(AhUtilsTest, NibbleConversion) {
60 for (int i = 0; i < 16; ++i) {
61 char c = Aleph::nibble_to_char(i);
62 EXPECT_EQ(i, Aleph::char_to_nibble(c));
63 }
64 EXPECT_EQ(Aleph::nibble_to_char(10), 'A');
65 EXPECT_EQ(Aleph::nibble_to_char(15), 'F');
66 EXPECT_EQ(Aleph::char_to_nibble('9'), 9);
67 EXPECT_EQ(Aleph::char_to_nibble('B'), 11);
68
69 // Assertion test (only in debug)
70 #ifndef NDEBUG
71 EXPECT_DEATH(Aleph::nibble_to_char(16), "");
72 EXPECT_DEATH(Aleph::char_to_nibble('G'), "");
73 #endif
74}
75
76// Tests for is_power_of_2() and next_power_of_2()
77TEST(AhUtilsTest, PowerOf2) {
78 EXPECT_TRUE(Aleph::is_power_of_2(1));
79 EXPECT_TRUE(Aleph::is_power_of_2(2));
80 EXPECT_TRUE(Aleph::is_power_of_2(16));
81 EXPECT_TRUE(Aleph::is_power_of_2(1024));
82 EXPECT_FALSE(Aleph::is_power_of_2(0));
83 EXPECT_FALSE(Aleph::is_power_of_2(3));
84 EXPECT_FALSE(Aleph::is_power_of_2(15));
85
86 EXPECT_EQ(Aleph::next_power_of_2(1), 1);
87 EXPECT_EQ(Aleph::next_power_of_2(2), 2);
88 EXPECT_EQ(Aleph::next_power_of_2(3), 4);
89 EXPECT_EQ(Aleph::next_power_of_2(7), 8);
90 EXPECT_EQ(Aleph::next_power_of_2(16), 16);
91 EXPECT_EQ(Aleph::next_power_of_2(17), 32);
92}
93
94// Tests for median()
95TEST(AhUtilsTest, Median) {
97 EXPECT_EQ(*Aleph::median(1, 2, 3, cmp), 2);
98 EXPECT_EQ(*Aleph::median(3, 1, 2, cmp), 2);
99 EXPECT_EQ(*Aleph::median(2, 3, 1, cmp), 2);
100 EXPECT_EQ(*Aleph::median(1, 1, 2, cmp), 1);
101 EXPECT_EQ(*Aleph::median(2, 1, 1, cmp), 1);
102 EXPECT_EQ(*Aleph::median(1, 2, 1, cmp), 1);
103 EXPECT_EQ(*Aleph::median(5, 5, 5, cmp), 5);
104
105 // Test with temporary comparator (thanks to refactoring)
106 EXPECT_EQ(*Aleph::median(10, 20, 15, Aleph::less<int>()), 15);
107}
108
109// Tests for interpolate() and extrapolate_*()
110TEST(AhUtilsTest, Interpolation) {
111 EXPECT_DOUBLE_EQ(Aleph::interpolate(0, 10, 0, 100, 5), 50.0);
112 EXPECT_DOUBLE_EQ(Aleph::interpolate(1, 2, 10, 20, 1.5), 15.0);
113 EXPECT_DOUBLE_EQ(Aleph::extrapolate_left(1, 2, 10, 20, 0), 0.0);
114 EXPECT_DOUBLE_EQ(Aleph::extrapolate_right(1, 2, 10, 20, 3), 30.0);
115
116 EXPECT_DOUBLE_EQ(Aleph::pow2(3.0), 9.0);
117 EXPECT_DOUBLE_EQ(Aleph::pow3(2.0), 8.0);
118}
119
120// Tests for are_near()
121TEST(AhUtilsTest, AreNear) {
122 EXPECT_TRUE(Aleph::are_near(1.0, 1.000001, 1e-5));
123 EXPECT_FALSE(Aleph::are_near(1.0, 1.0001, 1e-5));
124 EXPECT_TRUE(Aleph::are_near(-1.0, -1.000001, 1e-5));
125 EXPECT_FALSE(Aleph::are_near(-1.0, -1.0001, 1e-5));
126}
127
128// Tests for u_index and l_index
129TEST(AhUtilsTest, Indices) {
130 EXPECT_EQ(Aleph::u_index(10), 5);
131 EXPECT_EQ(Aleph::u_index(11), 5);
132 EXPECT_EQ(Aleph::l_index(5), 10);
133}
134
135// Tests for demangle and CLASSNAME_TO_STRING
136struct MyTestStruct {};
137TEST(AhUtilsTest, Demangle) {
138 std::string name = Aleph::demangle(typeid(int).name());
139 EXPECT_EQ(name, "int");
140
141 MyTestStruct s;
142 std::string className = CLASSNAME_TO_STRING(&s);
143 // The exact name may vary depending on the compiler/namespace, but it must contain MyTestStruct
144 EXPECT_TRUE(className.find("MyTestStruct") != std::string::npos);
145}
146
147// Tests for exists_file
148TEST(AhUtilsTest, ExistsFile) {
149 std::string filename = "test_exists_file.tmp";
150 std::ofstream outfile(filename);
151 outfile << "test";
152 outfile.close();
153
154 EXPECT_TRUE(Aleph::exists_file(filename));
155 std::remove(filename.c_str());
156 EXPECT_FALSE(Aleph::exists_file(filename));
157}
158
159// Tests for next_value, prev_value, is_normal_number
160TEST(AhUtilsTest, FloatUtils) {
161 double val = 1.0;
162 EXPECT_GT(Aleph::next_value(val), val);
163 EXPECT_LT(Aleph::prev_value(val), val);
164
165 EXPECT_TRUE(Aleph::is_normal_number(1.0));
166 EXPECT_TRUE(Aleph::is_normal_number(0.0));
167 EXPECT_TRUE(Aleph::is_normal_number(-0.0));
168
169 double inf = std::numeric_limits<double>::infinity();
170 double nan = std::numeric_limits<double>::quiet_NaN();
171
172 EXPECT_FALSE(Aleph::is_normal_number(inf));
173 EXPECT_FALSE(Aleph::is_normal_number(nan));
174}
175
176// Tests for error_msg
177TEST(AhUtilsTest, ErrorMsg) {
178 EXPECT_DEATH(Aleph::error_msg("Test Error"), "Test Error");
179}
180
181// Mock container to test Rvector
183 std::vector<int> data;
184
185 MockContainer(std::initializer_list<int> l) : data(l) {}
186
187 const int& get_first() const { return data.front(); }
188 const int& get_last() const { return data.back(); }
189
190 struct Iterator {
191 std::vector<int>::const_iterator it;
192 std::vector<int>::const_iterator end;
193
194 Iterator(const MockContainer& c) : it(c.data.begin()), end(c.data.end()) {}
195
196 bool has_curr() const { return it != end; }
197 const int& get_curr() const { return *it; }
198 void next() { ++it; }
199 };
200
201 Iterator get_it() const { return Iterator(*this); }
202 // For the second overload of Rvector that uses get_it(1)
203 Iterator get_it(int) const { return Iterator(*this); }
204};
205
206TEST(AhUtilsTest, Rvector) {
207 MockContainer c{1, 2, 3};
208
209 std::string r1 = Aleph::Rvector("vec", c);
210 EXPECT_EQ(r1, "vec <- c(1, 2, 3)");
211
212 // Note: The second overload of Rvector uses c.get_first() as the name
213 // and c.get_it(1) to iterate. In our mock, get_first returns int,
214 // so the name will be "1".
215 std::string r2 = Aleph::Rvector(c);
216 EXPECT_EQ(r2, "1 <- c(1, 2, 3)");
217}
218
219int main(int argc, char **argv) {
220 ::testing::InitGoogleTest(&argc, argv);
221 return RUN_ALL_TESTS();
222}
#define CLASSNAME_TO_STRING(class_ptr)
Given a pointer, it returns the class name.
Definition ahUtils.H:264
int main()
#define TEST(name)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Definition gmpfrxx.h:4118
size_t l_index(const size_t i)
Map a binary heap index to the index of its left child.
Definition ahUtils.H:213
double next_value(const double val)
Return the next representable floating-point value to val
Definition ahUtils.H:415
unsigned long next_power_of_2(unsigned long x)
In x is not exact power of 2, it returns the next power of 2.
Definition ahUtils.H:234
void error_msg(const std::string &msg)
Display message and abort program execution.
Definition ahUtils.H:270
const T * median(const T &a, const T &b, const T &c, const Compare &cmp=Compare())
Return a pointer to the median value among three elements.
Definition ahUtils.H:84
constexpr bool are_near(const double v1, const double v2, const double e) noexcept
Return true if v1 is within absolute distance e of v2.
Definition ahUtils.H:434
double extrapolate_right(const double x1, const double x2, const double y1, const double y2, const double x)
Basic linear extrapolation.
Definition ahUtils.H:404
size_t u_index(const size_t &i)
Map a binary heap index to the index of its parent.
Definition ahUtils.H:199
double interpolate(const double x1, const double x2, const double y1, const double y2, const double x)
Basic linear interpolation.
Definition ahUtils.H:350
double prev_value(const double val)
Return the next representable floating-point value of val towards the smallest positive normal number...
Definition ahUtils.H:425
bool is_even(const long n)
Return true if n is even.
Definition ahUtils.H:102
bool is_odd(const long n)
Return true if n is odd.
Definition ahUtils.H:111
double pow2(const double x)
Return x^2.
Definition ahUtils.H:382
char nibble_to_char(const int i)
Convert a 4-bit nibble stored in an int to its hex character.
Definition ahUtils.H:122
bool exists_file(const std::string &name)
Return true if it exists a file of name
Definition ahUtils.H:280
int char_to_nibble(const char c)
Convert a hex character in 0..9A..F to its 4-bit nibble value.
Definition ahUtils.H:137
std::string Rvector(const std::string &name, const C &c)
Return a string with R specification of a vector with name and data stored in container c
Definition ahUtils.H:292
bool is_normal_number(const double n)
Return true if a floating-point number is normal or zero.
Definition ahUtils.H:469
std::string demangle(const char *name)
Given a linker symbol name generated by a c++ compiler, this functions decodes it into a user level n...
Definition ahUtils.H:251
double extrapolate_left(const double x1, const double x2, const double y1, const double y2, const double x)
Basic linear extrapolation.
Definition ahUtils.H:372
double pow3(const double x)
Return x^3.
Definition ahUtils.H:387
bool is_power_of_2(unsigned long x)
Taken from http://stackoverflow.com/questions/3638431/determine-if-an-int-is-a-power-of-2-or-not-in-a...
Definition ahUtils.H:224
std::vector< int >::const_iterator end
Definition ah-utils.cc:192
Iterator(const MockContainer &c)
Definition ah-utils.cc:194
std::vector< int >::const_iterator it
Definition ah-utils.cc:191
bool has_curr() const
Definition ah-utils.cc:196
const int & get_curr() const
Definition ah-utils.cc:197
Iterator get_it() const
Definition ah-utils.cc:201
const int & get_last() const
Definition ah-utils.cc:188
MockContainer(std::initializer_list< int > l)
Definition ah-utils.cc:185
std::vector< int > data
Definition ah-utils.cc:183
const int & get_first() const
Definition ah-utils.cc:187
Iterator get_it(int) const
Definition ah-utils.cc:203
DynList< int > l