Add test for a custom type.
Custom type is implicitly constructible, implicitly castable to float and can be compared to int.
This commit is contained in:
parent
7225298698
commit
a4184811b1
2 changed files with 148 additions and 0 deletions
|
@ -9,6 +9,7 @@ add_executable(${PROJECT_NAME}
|
||||||
test_operators.cpp
|
test_operators.cpp
|
||||||
test_sequence_range.cpp
|
test_sequence_range.cpp
|
||||||
test_offset_getters.cpp
|
test_offset_getters.cpp
|
||||||
|
test_custom_type.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
|
147
test/unit/test_custom_type.cpp
Normal file
147
test/unit/test_custom_type.cpp
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015-2017 Michele "King_DuckZ" Santullo
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vectorwrapper/vectorwrapper.hpp"
|
||||||
|
#include "vectorwrapper/vector_cast.hpp"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int gcd (int a, int b) {
|
||||||
|
if ((a && b) == false)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int r, q, uRet;
|
||||||
|
|
||||||
|
do {
|
||||||
|
uRet = b;
|
||||||
|
|
||||||
|
q = a / b;
|
||||||
|
r = a - q * b;
|
||||||
|
|
||||||
|
a = b;
|
||||||
|
b = r;
|
||||||
|
} while (r);
|
||||||
|
return uRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rational {
|
||||||
|
public:
|
||||||
|
Rational() = default;
|
||||||
|
Rational (int num, int den) : m_n(num), m_d(den) {}
|
||||||
|
Rational (int num) : m_n(num), m_d(1) {}
|
||||||
|
Rational (const Rational&) = default;
|
||||||
|
Rational (Rational&&) = default;
|
||||||
|
~Rational() = default;
|
||||||
|
|
||||||
|
Rational& operator= (const Rational&) = default;
|
||||||
|
Rational& operator= (Rational&&) = default;
|
||||||
|
bool operator== (const Rational& o) const { return m_n == o.m_n and m_d == o.m_d; }
|
||||||
|
bool operator== (int o) const { return m_n == o and 1 == m_d; }
|
||||||
|
|
||||||
|
operator float() const { return static_cast<float>(m_n) / static_cast<float>(m_d); }
|
||||||
|
|
||||||
|
Rational& operator*= (const Rational& o) {
|
||||||
|
m_n *= o.m_n; m_d *= o.m_d; simplify(); return *this;
|
||||||
|
}
|
||||||
|
Rational& operator/= (const Rational& o) {
|
||||||
|
m_n *= o.m_d; m_d *= o.m_n; simplify(); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num() const { return m_n; }
|
||||||
|
int den() const { return m_d; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void simplify() { const int t = gcd(m_n, m_d); m_n /= t; m_d /= t; }
|
||||||
|
|
||||||
|
int m_n, m_d;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator== (int a, const Rational& b) {
|
||||||
|
return a == b.num() and b.den() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rational operator* (Rational a, const Rational& b) { a *= b; return a; }
|
||||||
|
Rational operator/ (Rational a, const Rational& b) { a /= b; return a; }
|
||||||
|
|
||||||
|
std::ostream& operator<< (std::ostream& os, const Rational& r) {
|
||||||
|
os << r.num() << '/' << r.den();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ThreeRationals {
|
||||||
|
Rational a, b, c;
|
||||||
|
};
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
namespace vwr {
|
||||||
|
template <>
|
||||||
|
struct VectorWrapperInfo<ThreeRationals> {
|
||||||
|
enum { dimensions = 3 };
|
||||||
|
typedef Rational scalar_type;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
offset_x = offsetof(ThreeRationals, a),
|
||||||
|
offset_y = offsetof(ThreeRationals, b),
|
||||||
|
offset_z = offsetof(ThreeRationals, c)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct VectorWrapperInfo<std::array<float, 3> > {
|
||||||
|
enum { dimensions = 3 };
|
||||||
|
typedef float scalar_type;
|
||||||
|
|
||||||
|
static scalar_type& get_at (size_type i, std::array<float, 3>& v) {
|
||||||
|
return v[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} //namespace vwr
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
typedef vwr::Vec<ThreeRationals> rvec3;
|
||||||
|
typedef vwr::Vec<std::array<float, 3> > fvec3;
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
|
TEST(vwr, custom_type) {
|
||||||
|
using vwr::vector_cast;
|
||||||
|
|
||||||
|
rvec3 rational3(
|
||||||
|
Rational(1),
|
||||||
|
Rational(1, 2),
|
||||||
|
Rational(1, 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
EXPECT_EQ(1, rational3.x());
|
||||||
|
EXPECT_EQ(Rational(1, 2), rational3.y());
|
||||||
|
EXPECT_EQ(Rational(1, 3), rational3.z());
|
||||||
|
|
||||||
|
fvec3 float3 = vector_cast<fvec3>(rational3);
|
||||||
|
EXPECT_EQ(1.0f, float3.x());
|
||||||
|
EXPECT_EQ(0.5f, float3.y());
|
||||||
|
|
||||||
|
rational3 *= 4;
|
||||||
|
EXPECT_EQ(4, rational3.x());
|
||||||
|
EXPECT_EQ(2, rational3.y());
|
||||||
|
EXPECT_EQ(Rational(4, 3), rational3.z());
|
||||||
|
|
||||||
|
rational3 /= 2;
|
||||||
|
EXPECT_EQ(2, rational3.x());
|
||||||
|
EXPECT_EQ(1, rational3.y());
|
||||||
|
EXPECT_EQ(Rational(2, 3), rational3.z());
|
||||||
|
}
|
Loading…
Reference in a new issue