mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-16 22:19:51 +07:00
more constexpr
This commit is contained in:
@@ -7,9 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
@@ -29,100 +26,103 @@ namespace vmath_hpp::detail
|
||||
template < typename T >
|
||||
class vec_base<T, 2> {
|
||||
public:
|
||||
T x, y;
|
||||
T data[2];
|
||||
public:
|
||||
constexpr vec_base() : x{}, y{} {}
|
||||
constexpr vec_base() : data{} {}
|
||||
constexpr explicit vec_base(uninit_t) {}
|
||||
|
||||
constexpr explicit vec_base(const T& v)
|
||||
: x{v}, y{v} {}
|
||||
: data{v, v} {}
|
||||
|
||||
constexpr vec_base(T x, T y)
|
||||
: x{std::move(x)}, y{std::move(y)} {}
|
||||
: data{std::move(x), std::move(y)} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 3>&& xy)
|
||||
: x{std::move(xy.x)} , y{std::move(xy.y)} {}
|
||||
: data{std::move(xy.x()), std::move(xy.y())} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 3>& xy)
|
||||
: x{xy.x} , y{xy.y} {}
|
||||
: data{xy.x(), xy.y()} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 4>&& xy)
|
||||
: x{std::move(xy.x)} , y{std::move(xy.y)} {}
|
||||
: data{std::move(xy.x()), std::move(xy.y())} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 4>& xy)
|
||||
: x{xy.x} , y{xy.y} {}
|
||||
: data{xy.x(), xy.y()} {}
|
||||
|
||||
constexpr T* data() noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& x() noexcept { return data[0]; }
|
||||
constexpr const T& x() const noexcept { return data[0]; }
|
||||
|
||||
constexpr const T* data() const noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& y() noexcept { return data[1]; }
|
||||
constexpr const T& y() const noexcept { return data[1]; }
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
class vec_base<T, 3> {
|
||||
public:
|
||||
T x, y, z;
|
||||
T data[3];
|
||||
public:
|
||||
constexpr vec_base() : x{}, y{}, z{} {}
|
||||
constexpr vec_base() : data{} {}
|
||||
constexpr explicit vec_base(uninit_t) {}
|
||||
|
||||
constexpr explicit vec_base(const T& v)
|
||||
: x{v}, y{v}, z{v} {}
|
||||
: data{v, v, v} {}
|
||||
|
||||
constexpr vec_base(T x, T y, T z)
|
||||
: x{std::move(x)}, y{std::move(y)}, z{std::move(z)} {}
|
||||
: data{std::move(x), std::move(y), std::move(z)} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 2>&& xy, T z)
|
||||
: x{std::move(xy.x)} , y{std::move(xy.y)} , z{std::move(z)} {}
|
||||
: data{std::move(xy.x()), std::move(xy.y()), std::move(z)} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 2>& xy, T z)
|
||||
: x{xy.x} , y{xy.y} , z{std::move(z)} {}
|
||||
: data{xy.x(), xy.y(), std::move(z)} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 4>&& xyz)
|
||||
: x{std::move(xyz.x)} , y{std::move(xyz.y)} , z{std::move(xyz.z)} {}
|
||||
: data{std::move(xyz.x()), std::move(xyz.y()), std::move(xyz.z())} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 4>& xyz)
|
||||
: x{xyz.x} , y{xyz.y} , z{xyz.z} {}
|
||||
: data{xyz.x(), xyz.y(), xyz.z()} {}
|
||||
|
||||
constexpr T* data() noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& x() noexcept { return data[0]; }
|
||||
constexpr const T& x() const noexcept { return data[0]; }
|
||||
|
||||
constexpr const T* data() const noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& y() noexcept { return data[1]; }
|
||||
constexpr const T& y() const noexcept { return data[1]; }
|
||||
|
||||
constexpr T& z() noexcept { return data[2]; }
|
||||
constexpr const T& z() const noexcept { return data[2]; }
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
class vec_base<T, 4> {
|
||||
public:
|
||||
T x, y, z, w;
|
||||
T data[4];
|
||||
public:
|
||||
constexpr vec_base() : x{}, y{}, z{}, w{} {}
|
||||
constexpr vec_base() : data{} {}
|
||||
constexpr explicit vec_base(uninit_t) {}
|
||||
|
||||
constexpr explicit vec_base(const T& v)
|
||||
: x{v}, y{v}, z{v}, w{v} {}
|
||||
: data{v, v, v, v} {}
|
||||
|
||||
constexpr vec_base(T x, T y, T z, T w)
|
||||
: x{std::move(x)}, y{std::move(y)}, z{std::move(z)}, w{std::move(w)} {}
|
||||
: data{std::move(x), std::move(y), std::move(z), std::move(w)} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 2>&& xy, T z, T w)
|
||||
: x{std::move(xy.x)} , y{std::move(xy.y)} , z{std::move(z)} , w{std::move(w)} {}
|
||||
: data{std::move(xy.x()), std::move(xy.y()), std::move(z), std::move(w)} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 2>& xy, T z, T w)
|
||||
: x{xy.x} , y{xy.y} , z{std::move(z)} , w{std::move(w)} {}
|
||||
: data{xy.x(), xy.y(), std::move(z), std::move(w)} {}
|
||||
|
||||
constexpr explicit vec_base(vec_base<T, 3>&& xyz, T w)
|
||||
: x{std::move(xyz.x)} , y{std::move(xyz.y)} , z{std::move(xyz.z)} , w{std::move(w)} {}
|
||||
: data{std::move(xyz.x()), std::move(xyz.y()), std::move(xyz.z()), std::move(w)} {}
|
||||
constexpr explicit vec_base(const vec_base<T, 3>& xyz, T w)
|
||||
: x{xyz.x} , y{xyz.y} , z{xyz.z} , w{std::move(w)} {}
|
||||
: data{xyz.x(), xyz.y(), xyz.z(), std::move(w)} {}
|
||||
|
||||
constexpr T* data() noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& x() noexcept { return data[0]; }
|
||||
constexpr const T& x() const noexcept { return data[0]; }
|
||||
|
||||
constexpr const T* data() const noexcept {
|
||||
return std::addressof(x);
|
||||
}
|
||||
constexpr T& y() noexcept { return data[1]; }
|
||||
constexpr const T& y() const noexcept { return data[1]; }
|
||||
|
||||
constexpr T& z() noexcept { return data[2]; }
|
||||
constexpr const T& z() const noexcept { return data[2]; }
|
||||
|
||||
constexpr T& w() noexcept { return data[3]; }
|
||||
constexpr const T& w() const noexcept { return data[3]; }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -158,21 +158,20 @@ namespace vmath_hpp
|
||||
vec(const vec&) = default;
|
||||
vec& operator=(const vec&) = default;
|
||||
|
||||
void fill(const value_type& v) {
|
||||
std::fill_n(begin(), size(), v);
|
||||
}
|
||||
|
||||
void swap(vec& other) noexcept(std::is_nothrow_swappable_v<T>) {
|
||||
std::swap_ranges(begin(), end(), other.begin());
|
||||
for ( std::size_t i = 0; i < Size; ++i ) {
|
||||
using std::swap;
|
||||
swap(data[i], other.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr iterator begin() noexcept { return iterator(data()); }
|
||||
constexpr const_iterator begin() const noexcept { return const_iterator(data()); }
|
||||
constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
|
||||
constexpr iterator begin() noexcept { return iterator(data); }
|
||||
constexpr const_iterator begin() const noexcept { return const_iterator(data); }
|
||||
constexpr const_iterator cbegin() const noexcept { return const_iterator(data); }
|
||||
|
||||
constexpr iterator end() noexcept { return iterator(data() + size()); }
|
||||
constexpr const_iterator end() const noexcept { return const_iterator(data() + size()); }
|
||||
constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
|
||||
constexpr iterator end() noexcept { return iterator(data + Size); }
|
||||
constexpr const_iterator end() const noexcept { return const_iterator(data + Size); }
|
||||
constexpr const_iterator cend() const noexcept { return const_iterator(data + Size); }
|
||||
|
||||
constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
|
||||
constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
|
||||
@@ -186,21 +185,26 @@ namespace vmath_hpp
|
||||
constexpr size_type max_size() const noexcept { return Size; }
|
||||
constexpr bool empty() const noexcept { return !Size; }
|
||||
|
||||
constexpr reference operator[](size_type index) noexcept { return data()[index]; }
|
||||
constexpr const_reference operator[](size_type index) const noexcept { return data()[index]; }
|
||||
constexpr reference operator[](size_type index) noexcept {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type index) const noexcept {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
constexpr reference at(size_type index) {
|
||||
if ( index >= size() ) {
|
||||
throw std::out_of_range("vec::at");
|
||||
if ( index < Size ) {
|
||||
return data[index];
|
||||
}
|
||||
return data()[index];
|
||||
throw std::out_of_range("vec::at");
|
||||
}
|
||||
|
||||
constexpr const_reference at(size_type index) const {
|
||||
if ( index >= size() ) {
|
||||
throw std::out_of_range("vec::at");
|
||||
if ( index < Size ) {
|
||||
return data[index];
|
||||
}
|
||||
return data()[index];
|
||||
throw std::out_of_range("vec::at");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -213,18 +217,31 @@ namespace vmath_hpp
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T, std::size_t Size >
|
||||
bool operator==(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
return std::equal(l.begin(), l.end(), r.begin());
|
||||
constexpr bool operator==(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
for ( std::size_t i = 0; i < Size; ++i ) {
|
||||
if ( !(l[i] == r[i]) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
bool operator!=(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
constexpr bool operator!=(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
bool operator<(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
|
||||
constexpr bool operator<(const vec<T, Size>& l, const vec<T, Size>& r) {
|
||||
for ( std::size_t i = 0; i < Size; ++i ) {
|
||||
if ( l[i] < r[i] ) {
|
||||
return true;
|
||||
}
|
||||
if ( r[i] < l[i] ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <vmath.hpp/vmath.hpp>
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include <vmath.hpp/vmath.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
@@ -24,34 +24,34 @@ TEST_CASE("vmath/vec") {
|
||||
|
||||
SECTION("ctors") {
|
||||
{
|
||||
REQUIRE(vec2i().x == 0);
|
||||
REQUIRE(vec2i().y == 0);
|
||||
STATIC_REQUIRE(vec2i().x() == 0);
|
||||
STATIC_REQUIRE(vec2i().y() == 0);
|
||||
|
||||
REQUIRE(vec2i(1).x == 1);
|
||||
REQUIRE(vec2i(1).y == 1);
|
||||
STATIC_REQUIRE(vec2i(1).x() == 1);
|
||||
STATIC_REQUIRE(vec2i(1).y() == 1);
|
||||
|
||||
REQUIRE(vec2i(1,2).x == 1);
|
||||
REQUIRE(vec2i(1,2).y == 2);
|
||||
STATIC_REQUIRE(vec2i(1,2).x() == 1);
|
||||
STATIC_REQUIRE(vec2i(1,2).y() == 2);
|
||||
}
|
||||
{
|
||||
vec2i v(1,2);
|
||||
vec2i v2 = v;
|
||||
REQUIRE(v2 == vec2i(1,2));
|
||||
constexpr vec2i v(1,2);
|
||||
constexpr vec2i v2 = v;
|
||||
STATIC_REQUIRE(v2 == vec2i(1,2));
|
||||
}
|
||||
{
|
||||
vec2i v(1,2);
|
||||
vec2i v2 = std::move(v);
|
||||
REQUIRE(v2 == vec2i(1,2));
|
||||
constexpr vec2i v(1,2);
|
||||
constexpr vec2i v2 = std::move(v);
|
||||
STATIC_REQUIRE(v2 == vec2i(1,2));
|
||||
}
|
||||
{
|
||||
REQUIRE(vec2i(vec3i(1,2,3)) == vec2i(1,2));
|
||||
REQUIRE(vec2i(vec4i(1,2,3,4)) == vec2i(1,2));
|
||||
STATIC_REQUIRE(vec2i(vec3i(1,2,3)) == vec2i(1,2));
|
||||
STATIC_REQUIRE(vec2i(vec4i(1,2,3,4)) == vec2i(1,2));
|
||||
|
||||
REQUIRE(vec3i(vec2i(1,2),3) == vec3i(1,2,3));
|
||||
REQUIRE(vec3i(vec4i(1,2,3,4)) == vec3i(1,2,3));
|
||||
STATIC_REQUIRE(vec3i(vec2i(1,2),3) == vec3i(1,2,3));
|
||||
STATIC_REQUIRE(vec3i(vec4i(1,2,3,4)) == vec3i(1,2,3));
|
||||
|
||||
REQUIRE(vec4i(vec2i(1,2),3,4) == vec4i(1,2,3,4));
|
||||
REQUIRE(vec4i(vec3i(1,2,3),4) == vec4i(1,2,3,4));
|
||||
STATIC_REQUIRE(vec4i(vec2i(1,2),3,4) == vec4i(1,2,3,4));
|
||||
STATIC_REQUIRE(vec4i(vec3i(1,2,3),4) == vec4i(1,2,3,4));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,12 +70,6 @@ TEST_CASE("vmath/vec") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("fill") {
|
||||
vec2i v(1,2);
|
||||
v.fill(4);
|
||||
REQUIRE(v == vec2i(4));
|
||||
}
|
||||
|
||||
SECTION("swap") {
|
||||
{
|
||||
vec2i v1(1,2);
|
||||
@@ -93,12 +87,6 @@ TEST_CASE("vmath/vec") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("data") {
|
||||
vec2i v(1,2);
|
||||
REQUIRE(v.data() == &v.x);
|
||||
REQUIRE(std::as_const(v).data() == &v.x);
|
||||
}
|
||||
|
||||
SECTION("iter") {
|
||||
{
|
||||
vec2i v(1,2);
|
||||
@@ -162,35 +150,69 @@ TEST_CASE("vmath/vec") {
|
||||
}
|
||||
|
||||
SECTION("operator[]") {
|
||||
REQUIRE(vec2i(1,2).x == 1);
|
||||
REQUIRE(vec2i(1,2).y == 2);
|
||||
REQUIRE(vec2i(1,2)[0] == 1);
|
||||
REQUIRE(vec2i(1,2)[1] == 2);
|
||||
{
|
||||
STATIC_REQUIRE(vec2i(1,2).x() == 1);
|
||||
STATIC_REQUIRE(vec2i(1,2).y() == 2);
|
||||
|
||||
STATIC_REQUIRE(vec3i(1,2,3).x() == 1);
|
||||
STATIC_REQUIRE(vec3i(1,2,3).y() == 2);
|
||||
STATIC_REQUIRE(vec3i(1,2,3).z() == 3);
|
||||
|
||||
STATIC_REQUIRE(vec4i(1,2,3,4).x() == 1);
|
||||
STATIC_REQUIRE(vec4i(1,2,3,4).y() == 2);
|
||||
STATIC_REQUIRE(vec4i(1,2,3,4).z() == 3);
|
||||
STATIC_REQUIRE(vec4i(1,2,3,4).w() == 4);
|
||||
}
|
||||
{
|
||||
STATIC_REQUIRE(vec2i(1,2)[0] == 1);
|
||||
STATIC_REQUIRE(vec2i(1,2)[1] == 2);
|
||||
}
|
||||
{
|
||||
vec2i v;
|
||||
v.x() = 1;
|
||||
v.y() = 2;
|
||||
REQUIRE(v == vec2i(1,2));
|
||||
}
|
||||
{
|
||||
vec3i v;
|
||||
v.x() = 1;
|
||||
v.y() = 2;
|
||||
v.z() = 3;
|
||||
REQUIRE(v == vec3i(1,2,3));
|
||||
}
|
||||
{
|
||||
vec4i v;
|
||||
v.x() = 1;
|
||||
v.y() = 2;
|
||||
v.z() = 3;
|
||||
v.w() = 4;
|
||||
REQUIRE(v == vec4i(1,2,3,4));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("at") {
|
||||
REQUIRE(vec2i(1,2).at(0) == 1);
|
||||
REQUIRE(vec2i(1,2).at(1) == 2);
|
||||
STATIC_REQUIRE(vec2i(1,2).at(0) == 1);
|
||||
STATIC_REQUIRE(vec2i(1,2).at(1) == 2);
|
||||
REQUIRE_THROWS_AS(vec2i(1,2).at(2), std::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("operator==/operator!=") {
|
||||
REQUIRE(vec2i(1,2) == vec2i(1,2));
|
||||
REQUIRE_FALSE(vec2i(1,2) == vec2i(2,2));
|
||||
REQUIRE_FALSE(vec2i(1,2) == vec2i(1,3));
|
||||
STATIC_REQUIRE(vec2i(1,2) == vec2i(1,2));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) == vec2i(2,2));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) == vec2i(1,3));
|
||||
|
||||
REQUIRE_FALSE(vec2i(1,2) != vec2i(1,2));
|
||||
REQUIRE(vec2i(1,2) != vec2i(2,2));
|
||||
REQUIRE(vec2i(1,2) != vec2i(1,3));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) != vec2i(1,2));
|
||||
STATIC_REQUIRE(vec2i(1,2) != vec2i(2,2));
|
||||
STATIC_REQUIRE(vec2i(1,2) != vec2i(1,3));
|
||||
}
|
||||
|
||||
SECTION("operator<") {
|
||||
REQUIRE_FALSE(vec2i(1,2) < vec2i(1,2));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) < vec2i(1,2));
|
||||
|
||||
REQUIRE(vec2i(1,1) < vec2i(1,2));
|
||||
REQUIRE_FALSE(vec2i(1,2) < vec2i(1,1));
|
||||
STATIC_REQUIRE(vec2i(1,1) < vec2i(1,2));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) < vec2i(1,1));
|
||||
|
||||
REQUIRE(vec2i(0,3) < vec2i(1,2));
|
||||
REQUIRE_FALSE(vec2i(1,2) < vec2i(0,3));
|
||||
STATIC_REQUIRE(vec2i(0,3) < vec2i(1,2));
|
||||
STATIC_REQUIRE_FALSE(vec2i(1,2) < vec2i(0,3));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user