110 lines
3.3 KiB
C++
110 lines
3.3 KiB
C++
/*
|
|
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
|
|
|
This file is part of MyCurry.
|
|
|
|
MyCurry is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
MyCurry is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "vectorwrapper/vectorwrapper.hpp"
|
|
#include "vectypes.hpp"
|
|
#include <array>
|
|
#include <cstdint>
|
|
#if !defined(NDEBUG)
|
|
# include <iostream>
|
|
#endif
|
|
#include <utility>
|
|
|
|
#define SPECIALIZE_ARRAY_VECTOR(TYPE, DIM) \
|
|
template <> \
|
|
struct VectorWrapperInfo<std::array<TYPE, DIM>> { \
|
|
enum { dimensions = DIM }; \
|
|
typedef TYPE scalar_type; \
|
|
typedef std::array<scalar_type, dimensions> vector_type; \
|
|
static scalar_type& get_at (size_t parIndex, vector_type& parVector) { \
|
|
return parVector[parIndex]; \
|
|
} \
|
|
}
|
|
|
|
namespace curry {
|
|
namespace vwr {
|
|
SPECIALIZE_ARRAY_VECTOR(float, 2);
|
|
SPECIALIZE_ARRAY_VECTOR(uint16_t, 2);
|
|
SPECIALIZE_ARRAY_VECTOR(int32_t, 2);
|
|
|
|
template <>
|
|
struct VectorWrapperInfo<cloonel::ushort2> {
|
|
enum { dimensions = 2 };
|
|
typedef cloonel::ushort2::scalar_type scalar_type;
|
|
typedef cloonel::ushort2 vector_type;
|
|
static scalar_type& get_at (size_type parIndex, vector_type& parVector) {
|
|
return parVector[parIndex];
|
|
}
|
|
};
|
|
template <>
|
|
struct VectorWrapperInfo<cloonel::float2> {
|
|
enum { dimensions = 2 };
|
|
typedef cloonel::float2::scalar_type scalar_type;
|
|
typedef cloonel::float2 vector_type;
|
|
static scalar_type& get_at (size_type parIndex, vector_type& parVector) {
|
|
return parVector[parIndex];
|
|
}
|
|
};
|
|
|
|
#if !defined(NDEBUG)
|
|
template <typename V>
|
|
std::ostream& operator<< (std::ostream& parStream, const Vec<V>& parVec) {
|
|
parStream << '<';
|
|
for (size_type z = 0; z < Vec<V>::dimensions - 1; ++z) {
|
|
std::cout << parVec[z] << ", ";
|
|
}
|
|
std::cout << parVec[Vec<V>::dimensions - 1] << '>';
|
|
return parStream;
|
|
}
|
|
#endif
|
|
|
|
namespace implem {
|
|
template <typename TO, typename FROM, std::size_t... I>
|
|
Vec<TO> vector_cast (const Vec<FROM>& parVec, Vec<TO>*, std::index_sequence<I...>) {
|
|
static_assert(
|
|
static_cast<int>(Vec<TO>::dimensions) == static_cast<int>(Vec<FROM>::dimensions),
|
|
"Mismatching dimensions"
|
|
);
|
|
static_assert(sizeof...(I) == Vec<TO>::dimensions, "Mismatching index count");
|
|
typedef typename Vec<TO>::scalar_type CastType;
|
|
|
|
return Vec<TO>(static_cast<CastType>(parVec[I])...);
|
|
}
|
|
} //namespace implem
|
|
|
|
template <typename TOVec, typename FROM>
|
|
TOVec vector_cast (const Vec<FROM>& parVec) {
|
|
TOVec* const to = nullptr;
|
|
return implem::vector_cast(parVec, to, std::make_index_sequence<Vec<FROM>::dimensions>());
|
|
}
|
|
} //namespace vwr
|
|
} //namespace curry
|
|
|
|
namespace curry {
|
|
using vec2f = vwr::Vec<std::array<float, 2>>;
|
|
using vec2us = vwr::Vec<std::array<uint16_t, 2>>;
|
|
using vec2i = vwr::Vec<std::array<int32_t, 2>>;
|
|
using cl_vec2us = vwr::Vec<cloonel::ushort2>;
|
|
using vwr::vector_cast;
|
|
} //namespace curry
|
|
|
|
#undef SPECIALIZE_ARRAY_VECTOR
|