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_sequence_range.cpp
|
||||
test_offset_getters.cpp
|
||||
test_custom_type.cpp
|
||||
)
|
||||
|
||||
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